并发流
public class StreamTest01 {
public static void main(String[] args) {
Stream<String> s = Stream.of("hello", "hello", "world");
//String collect = s.collect(Collectors.joining(",","《","》")); //《hello,hello,world》
//toCollection
//ArrayList<String> list = s.collect(Collectors.toCollection(() -> new ArrayList<>())); //[hello, hello, world]
TreeSet<String> set = s.collect(Collectors.toCollection(TreeSet::new)); //[hello, world]
System.out.println(set);
//iterate
List<Integer> x = Stream.iterate(2, item -> item + 2).limit(5).collect(Collectors.toList());// item==2 [2, 4, 6, 8, 10]
//栗子:找出该流中大于2的元素,然后将每个元素乘以2,然后忽略掉流中的前两个质素,然后再取流中的前两个元素,最后求出流中元素的总和。
Stream<Integer> stream = Stream.iterate(1, e -> e + 2).limit(6); //[1, 3, 5, 7, 9, 11]
OptionalInt max = stream.filter(e -> e > 2).mapToInt(e -> e * 2).skip(2).limit(2).max();
if (max.isPresent()) {
System.out.println(max.getAsInt());
}
//流只能使用一次,每次中间操作都会产生一个新的流,供给下次操作
//流是惰性求值,如果没有终止操作,只有中间操作,那么流就不会执行
//如:
List<String> list = Arrays.asList("ni", "hao");
list.stream().map(
e->{
String upper=e.toUpperCase();
System.out.println("to upper");
return upper;
}
);
// 没有终止操作,map方法不会执行,上述代码不会打印任何东西
list.stream().map(
e->{
String upper=e.toUpperCase();
System.out.println("to upper");
return upper;
}
).collect(Collectors.toList());
// 打印:
// to upper
// to upper
}
}
串行流和并行流对比:
public class StreamTest02 {
public static void main(String[] args) {
List<String> list=new ArrayList<>(5000000);
for (int i = 0; i <5000000 ; i++) {
list.add(UUID.randomUUID().toString());
}
System.out.println("串行流开始排序");
long start = System.nanoTime();
list.stream().sorted().count();
long end = System.nanoTime();
Long millis= TimeUnit.NANOSECONDS.toMillis(end-start);
System.out.println("串行流用时"+millis+"毫秒");
System.out.println("并行流开始排序");
long s = System.nanoTime();
list.parallelStream().sorted().count();
long e = System.nanoTime();
Long m= TimeUnit.NANOSECONDS.toMillis(e-s);
System.out.println("并行流用时"+m+"毫秒");
}
}
console:
串行流开始排序
串行流用时4707毫秒
并行流开始排序
并行流用时1852毫秒
Process finished with exit code 0
流的短路
注:如果一个流中有若干个操作,流的执行顺序并不是将第一个操作作用于所有元素,然后再将第二个操作作用于所有元素,以此类推,直至所有操作执行完(如果是这样的话,一个流中有多少个中间操作,元素就会被遍历多少次)。而是从第一个元素开始,执行完所有的操作,再到下一个元素执行完所有的操作,以此类推,遍历完所有的元素,所以,一个流执行完,共遍历了一次所有元素。
非短路操作
流的非短路操作:
就是所有的元素都遍厉完(但是单个元素在执行所有操作时,也可能发生短路而跳过后续操作,直接开始下一个元素),直到最后才结束.用来收集成自己想要的数据. 方法有: 遍厉 forEach 归约 reduce 最大值 max 最小值 min 聚合 collect 计数 count 遍厉 forEach
public class StreamTest03 {
public static void main(String[] args) {
List<Integer> words = Arrays.asList(6,4,6);
long count = words.stream().filter(item -> {
System.out.println("-------------------------");
System.out.println("filter1:一次过滤大于4");
return item > 4;
}
).filter(item -> {
System.out.println("filter2:二次过滤大于10");
return item < 10;
}
).count();
}
}
-------------------------
filter1:一次过滤大于4
filter2:二次过滤大于10
-------------------------
filter1:一次过滤大于4
-------------------------
filter1:一次过滤大于4
filter2:二次过滤大于10
Process finished with exit code 0
从打印语句可以看出,每个元素都挨个执行了操作,但是元素“4”,没有执行第二个filter,因为第一filter已经不满足,发生短路,不会再执行后续操作。
短路操作
类似于在Java中短路运算符”&&”(与) 和”||”
顾名思义,短路运算符具有短路功能. |-如果 “&&” 运算符的第一个表达式为false,则第二个表达式就不会执行 ,如果 “||” 运算符的第一个表达式为true,则第二个表达式就不会执行
流的一些操作也会短路,比如findfirst(),在流的执行过程中,如果发现一个符合所有操作的元素,则后续元素就不会再执行。
public class StreamTest03 {
public static void main(String[] args) {
List<Integer> words = Arrays.asList(2,6,7,6);
words.stream().filter(item -> {
System.out.println("-------------------------");
System.out.println("filter1:一次过滤大于4");
return item> 4;
}
).filter(item -> {
System.out.println("filter2:二次过滤大于5");
return item< 10;
}
).map(item -> {
System.out.println("map:当前元素为"+item);
return item;
}).findFirst();
}
}
-------------------------
filter1:一次过滤大于4
-------------------------
filter1:一次过滤大于4
filter2:二次过滤大于5
map:当前元素为6
Process finished with exit code 0
可以看出,一共遍历了两个元素,后续元素被短路掉。
给个饭钱?
- Post link: http://sovzn.github.io/2022/10/29/%E6%B5%81%E7%9A%84%E7%9F%AD%E8%B7%AF%E4%B8%8E%E5%B9%B6%E5%8F%91%E6%B5%81/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues