JDK Stream

时间: 2023-07-18 admin 互联网

JDK Stream

JDK Stream

方法名JDK版本备注
创建Streamof(T… )8
empty()8创建空的Stream流
generate()8生成无限流
iterate()9创建无限流
ofNullable()9类似于Optional ofNullable()
映射和过滤filter()8
map[int double long]()8一一映射
flatMap[int double long]()81、一对多映射
抽取流和组合流limit()8
skip()8跳过前几个,和limit互补
takeWhile()9当满足条件留下
dropWhile()9满足条件丢弃
concat()8连接两个流,静态方法
其余流的转换distinct()8去除重复数值
sorted()8按照自然顺序排序
peek()8一般对元素的内部属性进行调整,类型不发生改变
结束操作(约简操作)max()8最大值
min()8最小值
count()8统计数量
findFirst8找出第一个,返回Optional
findAny8找出任意一个,返回Optional
anyMatch8任意一个匹配,boolean
allMatch8全部匹配,boolean
noneMatch8没有匹配的,boolean
reducereduce(accumulator)8执行累加,返回Optional
reduce(identify, accumulator)8带有幺元数,返回固定值
reduce(identify, accumulator, combiner)8累加器和组合器
收集操作forEach()8遍历所有流元素
toArray([Integer[]::new])8转为类型对象数组。默认为Object数组
collect(Collectors.toList())8转为list
collect(Collectors.toSet())8转为Set
collect(Collectors.toCollection())8转为自定义集合
collect(Collectors.summarizingInt())8转为数学统计对象
映射到表中toMap(key, value)8冲突会报错
toMap(key, value, overload)8指明冲突后value的取值
toMap(key, value, overload / exception, TreeMap::new)8
分组和分区groupingBy()8分组
partitionBy()8分区
下游收集器groupingBy(Person::getGender, Collectors.toSet())8分组结果为Set去重
groupingBy(Person::getGender, Collectors.counting())8分组结果进行计数
groupingBy(Person::getGender, Collectors.summingLong(Person::getId))8分组结果求和
groupingBy(Person::getGender, Collectors.summarizingLong(Person::getId))8分组结果转为数学统计
groupingBy(Person::getGender, Collectors.maxBy(Comparator.comparing(Person::getName)8分组结果求取最大值
groupingBy(Person::getGender, Collectors.minBy(Comparator.comparing(Person::getName))8同上,最小值
groupingBy(Person::getGender, Collectors.collectingAndThen(Collectors.toSet(), Set::size))8先收集在转换
groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toSet()))8先转换在收集
基本类型流range8获取一定范围内的数据流
rangeClosed8同上,闭区间
of8直接创建数据流
toArray()8转为int[]
sum / average/ min / max8计算结果
summaryStatistics8数学计算
boxed8获得包装器对象Stream<Integer>
Radom.ints()8随机产生数据流,不可分割(无法使用并行流)
并行流parallel()8并行处理
unordered()8不排序

1. 创建Stream

方法名JDK版本备注
of(T… )8
empty()8创建空的Stream流
generate()8生成无限流
iterate()9创建无限流
ofNullable()9类似于Optional ofNullable()
public class MyStreamTest {@Testpublic void test01() {List<Integer> list = Arrays.asList(1, 2, 3);Stream<Integer> stream = list.stream();Stream<Integer> stream1 = Stream.of(1, 2, 3);Stream<List<Integer>> stream2 = Stream.empty();Stream<String> generate = Stream.generate(() -> "Hello World");Stream<Double> generate1 = Stream.generate(Math::random);Stream<BigInteger> iterate = Stream.iterate(BigInteger.ONE, i -> i.add(BigInteger.ONE));// JDK9 优化有限流// Stream<BigInteger> iterate2 = Stream.iterate(BigInteger.ONE, i -> i.compareTo(new BigInteger("100")) < 0,i -> i.add(BigInteger.ONE));// Stream.ofNullable(); JDK9增强generate.forEach(System.out::println);}
}

2. 映射和过滤

方法名JDK版本备注
filter()8过滤
map[int double long]()8一一映射
flatMap[int double long]()81、一对多映射

流如果是empty()创建的则不会通过map,如果流中包含null则会通过map

public class MyStreamTest {@Testpublic void test05() {Stream<String> stream = Stream.of("Hello", "World");stream.filter(i -> i.length() > 3).map(String::toUpperCase).forEach(System.out::print);stream = Stream.of("Hello", "World");stream.flatMap(s -> {String[] array = s.split("");return Stream.of(array);}).forEach(System.out::println);stream = Stream.empty();stream.map(i -> {System.out.println("不会通过");return i;});}
}

3. 抽取流和组合流

方法名JDK版本备注
limit()8限制输出个数
skip()8跳过前几个,和limit互补
takeWhile()9当满足条件留下
dropWhile()9满足条件丢弃
concat()8连接两个流,静态方法
public class MyStreamTest {@Testpublic void test03() {Stream<String> stream = Stream.of("Hello", "World");stream.limit(2).skip(0).forEach(System.out::println);Stream<String> stream1 = Stream.of("Hello", "World");Stream<String> stream2 = Stream.of("Hello", "World");Stream<String> stream3 = Stream.concat(stream1, stream2);}
}

4. 其余流的转换

方法名JDK版本备注
distinct()8去除重复数值
sorted()8按照自然顺序排序
peek()8一般对元素的内部属性进行调整,类型不发生改变
public class MyStreamTest {@Testpublic void test04() {Stream<String> stream = Stream.of(null, "Hello", "World");stream.distinct().sorted(String::compareToIgnoreCase)  // 忽略大小写.peek(s -> System.out.println(s.toUpperCase())).forEach(System.out::println);}
}

5. 结束操作(约简操作)

方法名JDK版本备注
max()8最大值
min()8最小值
count()8统计数量
findFirst8找出第一个,返回Optional
findAny8找出任意一个,返回Optional
anyMatch8任意一个匹配,boolean
allMatch8全部匹配,boolean
noneMatch8没有匹配的,boolean
public class MyStreamTest {public void test05() {Stream<Integer> stream = Stream.of(11, 2, 49, 4, 34);Optional<Integer> max = stream.max(Comparator.reverseOrder());Optional<Integer> min = stream.min(Comparator.naturalOrder());long count = stream.count();Optional<Integer> first = stream.findFirst();Optional<Integer> any = stream.parallel().findAny();boolean anyMatch = stream.parallel().anyMatch(integer -> integer > 5);boolean allMatch = stream.parallel().allMatch(integer -> integer > 0);boolean noneMatch = stream.parallel().noneMatch(i -> i > 100);}
}

reduce

方法名JDK版本备注
reduce(accumulator)8执行累加,返回Optional
reduce(identify, accumulator)8带有幺元数,返回固定值
reduce(identify, accumulator, combiner)8累加器和组合器
public class MyStreamTest {@Testpublic void test10() {Stream<Integer> stream = Stream.of(1, 2, 3);Optional<Integer> reduce = stream.reduce((integer, integer2) -> integer + integer2);Integer reduce1 = stream.reduce(0, Integer::sum);Stream<String> stringStream = Stream.of("Hello", "World");Integer reduce2 = stringStream.reduce(0, (total, word) -> total + word.length(), (t1, t2) -> t1 + t2);}
}

6. 收集操作

方法名JDK版本备注
forEach()8遍历所有流元素
toArray([Integer[]::new])8转为类型对象数组。默认为Object数组
collect(Collectors.toList())8转为list
collect(Collectors.toSet())8转为Set
collect(Collectors.toCollection())8转为自定义集合
collect(Collectors.summarizingInt())8转为数学统计对象
public class MyStreamTest {@Testpublic void test06() {Stream<Integer> stream = Stream.of(1, 2, 3);stream.forEach(System.out::println);Object[] objects = stream.toArray();Integer[] array = stream.toArray(Integer[]::new);int[] array1 = stream.mapToInt(Integer::intValue).toArray();List<Integer> collect = stream.collect(Collectors.toList());Set<Integer> collect1 = stream.collect(Collectors.toSet());TreeSet<Integer> collect2 = stream.collect(Collectors.toCollection(TreeSet::new));IntSummaryStatistics statistics = stream.collect(Collectors.summarizingInt(Integer::intValue));statistics.getMin();statistics.getMax();statistics.getCount();statistics.getAverage();statistics.getSum();}
}

映射到表中

方法名JDK版本备注
toMap(key, value)8冲突会报错
toMap(key, value, overload)8指明冲突后value的取值
toMap(key, value, overload / exception, TreeMap::new)8指定映射表的类型
public class MyStreamTest {@Testpublic void test07() {Stream<Person> personStream = Stream.of(new Person(1L, "男", "小明"), new Person(2L, "女", "小红"));Map<Long, String> collect = personStream.collect(Collectors.toMap(Person::getId, Person::getName));Map<Long, Person> map = personStream.collect(Collectors.toMap(Person::getId, Function.identity()));Map<Long, Person> map2 = personStream.collect(Collectors.toMap(Person::getId, Function.identity(), (person, person2) -> person));TreeMap<Long, Person> map3 = personStream.collect(Collectors.toMap(Person::getId, Function.identity(), (person, person2) -> {throw new IllegalStateException();}, TreeMap::new));}
}

7. 分组和分区

方法名JDK版本备注
groupingBy()8分组
partitionBy()8分区
public class MyStreamTest {@Testpublic void test08() {Stream<Person> personStream = Stream.of(new Person(1L, "男", "小明"), new Person(2L, "女", "小红"));Map<String, List<Person>> collect = personStream.collect(Collectors.groupingBy(Person::getGender));Map<Boolean, List<Person>> collect1 = personStream.collect(Collectors.partitioningBy(person -> person.getId() > 1));}
}

下游收集器

方法名JDK版本备注
groupingBy(Person::getGender, Collectors.toSet())8分组结果为Set去重
groupingBy(Person::getGender, Collectors.counting())8分组结果进行计数
groupingBy(Person::getGender, Collectors.summingLong(Person::getId))8分组结果求和
groupingBy(Person::getGender, Collectors.summarizingLong(Person::getId))8分组结果转为数学统计
groupingBy(Person::getGender, Collectors.maxBy(Comparator.comparing(Person::getName)8分组结果求取最大值
groupingBy(Person::getGender, Collectors.minBy(Comparator.comparing(Person::getName))8同上,最小值
groupingBy(Person::getGender, Collectors.collectingAndThen(Collectors.toSet(), Set::size))8先收集在转换
groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toSet()))8先转换在收集

同样适用于partitionBy()

public class MyStreamTest {@Testpublic void test09() {Stream<Person> personStream = Stream.of(new Person(1L, "男", "小明"), new Person(2L, "女", "小红"));Map<String, Set<Person>> collect = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.toSet()));Map<String, Long> collect1 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.counting()));Map<String, Long> collect2 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.summingLong(Person::getId)));Map<String, LongSummaryStatistics> collect3 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.summarizingLong(Person::getId)));Map<String, Optional<Person>> collect4 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.maxBy(Comparator.comparing(Person::getName))));Map<String, Optional<Person>> collect5 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.minBy(Comparator.comparing(Person::getName))));// 去重复操作 先收集到Set在统计Map<String, Integer> collect6 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.collectingAndThen(Collectors.toSet(), Set::size)));Map<String, Set<String>> collect7 = personStream.collect(Collectors.groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toSet())));}
}

8. 基本类型流

方法名JDK版本备注
range8获取一定范围内的数据流
rangeClosed8同上,闭区间
of8直接创建数据流
toArray()8转为int[]
sum / average/ min / max8计算结果
summaryStatistics8数学计算
boxed8获得包装器对象Stream<Integer>
Radom.ints()8随机产生数据流,不可分割(无法使用并行流)
public class MyStreamTest {@Testpublic void test11() {IntStream stream = IntStream.of(1, 2, 3, 4);IntStream intStream = IntStream.rangeClosed(0, 10);int[] ints = stream.toArray();int sum = stream.sum();IntSummaryStatistics statistics = stream.summaryStatistics();long sum1 = statistics.getSum();Stream<Integer> boxed = intStream.boxed();String str = "Hello World";IntStream chars = str.chars();IntStream points = str.codePoints();List<Character> collect = chars.mapToObj(operand -> (char) operand).collect(Collectors.toList());Random random = new Random();IntStream stream1 = random.ints(0, 10);DoubleStream doubleStream = random.doubles(0, 10);}
}

9. 并行流

方法名JDK版本备注
parallel()8并行处理
unordered()8不排序

并行流 只要在终结方法之前处于并行状态,所有的中间操作都会被认定为并行操作,并不是所有的流都可以用来加速操作。

  1. 并行化会带来更大的资源损耗问题
  2. 只有底层的数据源可以被有效分割的时候并行化才有意义 Random.ints()产生的流不可分割,转为使用SplittableRandom.ints()
  3. 并行流使用的线程池可能会由于处理密集操作而其他IO操作被阻塞死
public class MyStreamTest {@Testpublic void test12() {Stream<String> stringStream = Stream.of("Hello", "World");// 无状态 不会处于并发安全问题Map<Integer, Long> collect = stringStream.parallel().filter(s -> s.length() > 3).collect(Collectors.groupingBy(String::length, Collectors.counting()));// 当对顺序要求不高的时候, 效率更高Stream<String> limit = stringStream.parallel().unordered().limit(10);}
}