Java流操作——Stream(一)
文章目录
- Java流操作——Stream(一)
- 前言
- 一、流是什么?
- 二、流的使用
- 1.流的创建
- 2.filter、map、distinct、sorted和peek的使用
- 3.抽取子流和连接流limit,skip,concat
- 4.约简操作count,min,max,findFirst,findAny,anyMatch,allMatch,noneMatch
前言
流是一种用来以“做什么而非怎么做”的方式处理集合。
一、流是什么?
平常在处理集合时我们会迭代遍历集合,例如我们统计长度大于3的字符串时会用以下for循环去一个一个遍历然后判断条件。
public static void main(String[] args){
List<String> words= Arrays.asList("ABC","ewqwrqr","fsfasfa","faeqrqtq");
int count=0;
for (String word : words) {
if(word.length()>3){
count++;
}
}
System.out.println(count);
}
在使用流操作时 我们只需要先调用stream方法产生一个流,然后filter方法会返回过滤后的一个新流,count方法会将流简化为一个结果返回。
public static void main(String[] args){
List<String> words= Arrays.asList("ABC","ewqwrqr","fsfasfa","faeqrqtq");
long count=words.stream().filter(x->x.length()>3).count();
System.out.println(count);
}
对比以上方法,我们可以发现流的操作比普通的循环遍历更简洁明了,每一步都可以通过方法名看出每一步操作的意义。在以上流示例中我们只需要指明每一步需要做什么,而至于怎么循环,在哪个线程去操作完成我们不需要关心。
二、流的使用
1.流的创建
//通过给定元素创建流
Stream<String> stream= Stream.of("ABC","ewqwrqr","fsfasfa","faeqrqtq");
//创建一个不包含任何元素的流
Stream<String> stream1= Stream.empty();
//创建一个无限流反复调用函数s构成
Stream<Integer> stream2= Stream.generate(()->0);
//创建一个无限流通过函数x在种子数据上操作生成
Stream<BigInteger> stream3= Stream.iterate(BigInteger.ZERO,x->x.add(BigInteger.ONE));
//创建一个流通过指定文件的行
Stream<String> stream4= Files.lines(Paths.get(""), StandardCharsets.UTF_8);
2.filter、map、distinct、sorted和peek的使用
- filter、map流
List<String> words= Arrays.asList("ABC","ewqwrqr","fsfasfa","faeqrqtq");
//返回一个与某种条件匹配后的新流,filter的引元时Predicate<T>,即从T到boolean的函数
Stream<String> stream1= words.stream().filter(x->x.length()>3);
//通过某种方式转换流中的值,使用map时会有一个函数应用在每个值上
Stream<String> stream2= words.stream().map(String::toLowerCase);
Stream<String> stream3= words.stream().map(s->s.substring(0,1));
- distinct流,过滤重复元素,通过equals()方法判断两元素是否相同
//剔除相同元素,打印出ABCD
List<String> contact= Arrays.asList("A","B","C","D","D","C");
Stream<String> stream = contact.stream().distinct();
- sorted排序
//sorted排序,按照字符串长度排序
List<String> contact= Arrays.asList("Dream","Busy","Cat","Dog");
Stream<String> stream = contact.stream().sorted(Comparator.comparing(String::length));
- peek会产生一个新流,它的元素与原来流中元素相同,但是在每次获取一个元素的时候,都会调用一个函数
//产生一个与原来流中国元素相同的新流,同时打印每个元素的长度
List<String> contact= Arrays.asList("Dream","Busy","Cat","Dog");
Stream<String> stream = contact.stream().peek(e-> System.out.println(e.length()));
3.抽取子流和连接流limit,skip,concat
- stream.limit(n)会返回当前流中前n个元素的新流
//产生一个包含100个随机数的流
Stream<Double> randoms=Stream.generate(Math::random).limit(100);
- stream.skip(n)正好相反,他会丢弃前n个元素
//跳过第一个元素,打印出BCD
List<String> contact= Arrays.asList("A","B","C","D");
Stream<String> random=contact.stream().skip(1);
- stream的concat方法将两个流连接起来
//拼接两个流,打印出ABCD
List<String> contact= Arrays.asList("A","B");
List<String> contact2= Arrays.asList("C","D");
Stream<String> stream = Stream.concat(contact.stream(), contact2.stream());
4.约简操作count,min,max,findFirst,findAny,anyMatch,allMatch,noneMatch
约简操作是一种终结操作,他会将流约简为在程序中可以使用的非流值。如count,min,max,findFirst,findAny,anyMatch,allMatch,noneMatch
Stream<String> contact= Stream.of("Dream","Busy","Cat","Dog");
//返回流中元素个数
long count =contact.count();
//返回流中最大值
Optional<String> max = contact.max(String::compareToIgnoreCase);
//返回流中最小值
Optional<String> min = contact.min(String::compareToIgnoreCase);
//找到第一个D开头的字符串
Optional<String> optional = contact.filter(x -> x.startsWith("Q")).findFirst();
//判断是否存在以D开头的字符串
boolean q = contact.anyMatch(x -> x.startsWith("Q"));
//判断是否所有字符串都以D开头的字符串
boolean b = contact.allMatch(x -> x.startsWith("Q"));
//判断是否所有字符串都不以D开头的字符串
boolean p = contact.noneMatch(x -> x.startsWith("Q"));