| 方法名 | JDK版本 | 备注 |
---|
创建Stream | of(T… ) | 8 | |
| empty() | 8 | 创建空的Stream流 |
| generate() | 8 | 生成无限流 |
| iterate() | 9 | 创建无限流 |
| ofNullable() | 9 | 类似于Optional ofNullable() |
| 映射和过滤 | filter() | 8 |
| map[int double long]() | 8 | 一一映射 |
| flatMap[int double long]() | 8 | 1、一对多映射 |
抽取流和组合流 | limit() | 8 | |
| skip() | 8 | 跳过前几个,和limit互补 |
| takeWhile() | 9 | 当满足条件留下 |
| dropWhile() | 9 | 满足条件丢弃 |
| concat() | 8 | 连接两个流,静态方法 |
其余流的转换 | distinct() | 8 | 去除重复数值 |
| sorted() | 8 | 按照自然顺序排序 |
| peek() | 8 | 一般对元素的内部属性进行调整,类型不发生改变 |
结束操作(约简操作) | max() | 8 | 最大值 |
| min() | 8 | 最小值 |
| count() | 8 | 统计数量 |
| findFirst | 8 | 找出第一个,返回Optional |
| findAny | 8 | 找出任意一个,返回Optional |
| anyMatch | 8 | 任意一个匹配,boolean |
| allMatch | 8 | 全部匹配,boolean |
| noneMatch | 8 | 没有匹配的,boolean |
reduce | reduce(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 | 先转换在收集 |
基本类型流 | range | 8 | 获取一定范围内的数据流 |
| rangeClosed | 8 | 同上,闭区间 |
| of | 8 | 直接创建数据流 |
| toArray() | 8 | 转为int[] |
| sum / average/ min / max | 8 | 计算结果 |
| summaryStatistics | 8 | 数学计算 |
| boxed | 8 | 获得包装器对象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 {
@Test
public 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));
generate.forEach(System.out::println);
}
}
2. 映射和过滤
方法名 | JDK版本 | 备注 |
---|
filter() | 8 | 过滤 |
map[int double long]() | 8 | 一一映射 |
flatMap[int double long]() | 8 | 1、一对多映射 |
流如果是empty()创建的则不会通过map,如果流中包含null则会通过map
public class MyStreamTest {
@Test
public 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 {
@Test
public 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 {
@Test
public 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 | 统计数量 |
findFirst | 8 | 找出第一个,返回Optional |
findAny | 8 | 找出任意一个,返回Optional |
anyMatch | 8 | 任意一个匹配,boolean |
allMatch | 8 | 全部匹配,boolean |
noneMatch | 8 | 没有匹配的,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 {
@Test
public 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 {
@Test
public 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 {
@Test
public 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 {
@Test
public 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 {
@Test
public 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))));
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版本 | 备注 |
---|
range | 8 | 获取一定范围内的数据流 |
rangeClosed | 8 | 同上,闭区间 |
of | 8 | 直接创建数据流 |
toArray() | 8 | 转为int[] |
sum / average/ min / max | 8 | 计算结果 |
summaryStatistics | 8 | 数学计算 |
boxed | 8 | 获得包装器对象Stream<Integer> |
Radom.ints() | 8 | 随机产生数据流,不可分割(无法使用并行流) |
public class MyStreamTest {
@Test
public 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 | 不排序 |
并行流 只要在终结方法之前处于并行状态,所有的中间操作都会被认定为并行操作,并不是所有的流都可以用来加速操作。
- 并行化会带来更大的资源损耗问题
- 只有底层的数据源可以被有效分割的时候并行化才有意义 Random.ints()产生的流不可分割,转为使用SplittableRandom.ints()
- 并行流使用的线程池可能会由于处理密集操作而其他IO操作被阻塞死
public class MyStreamTest {
@Test
public 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);
}
}