终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,
流进行了终止操作后,不能再次使用
1. 常用
- allMatch(Predicate p):检查是否匹配所有元素
- anyMatch(Predicate p):检查是否至少匹配一个元素
boolean bl = emps.stream().allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY))
boolean bl1 = emps.stream().anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY))
- noneMatch(Predicate p):检查是否没有匹配所有元素
- findFirst() :返回第一个元素
- findAny() :返回当前流中的任意元素
- forEach(Consumer c) :内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了)
- count()
- max(Comparator c)
- min(Comparator c)
2. 收集
2.1. 将元素收集到列表或集合中
- static <T> Collector<T,?,List<T>> tolist()
- static <T> Collector<T,?,List<T>> tolUnmodifiablelist() 10
- static <T> Collector<T,?,Set<T>> toSet()
- static <T>Collector<T,?,Set<T>> tolUnmodifiableSet()
List<Employee> emps = list.stream().collect(Collectors.toList())
Set<Employee> emps = list.stream().collect(Collectors.toSet());
2.2. 将元素收集到任意集合
可以传递一个诸如TreeSet::new的构造器引用。
static <T,C extends Collection<T>>Collector<T,?,C> toCollection(Supplier<C> collectionFactory)
Collection<Employee> emps=list.stream().collect(Collectors.toCollection(ArrayList::new));
2.3. 收集到映射表
产生一个收集器,它会产生一个映射表、不可修改的映射表或并发映射表。keyMapper 和 valueMapper 函数会应用于每个收集到的元素上,从而在所产生的映射表中生成一个键/值项。默认情况下,当两个元素产生相同的键时,会抛出一个IllegalStateException异常。你可以提供一个mergeFunction来合并具有相同键的值。默认情况下,其结果是一个Hashhap或ConcurrentHashMap。你可以提供一个 mapSupplier,它会产生所期望的映射表实例
Map<Integer, String> idToName = people().collect(
Collectors.toMap(Person::getId, Person::getName));
Map<Integer, Person> idToPerson = people().collect(
Collectors.toMap(Person::getId, Function.identity())); //value 为当前people
Stream<Locale> locales = Stream.of(Locale.getAvailableLocales());
Map<String, String> languageNames = locales.collect(
Collectors.toMap(Locale::getDisplayLanguage,l -> l.getDisplayLanguage(l),
(existingValue, newValue) -> existingValue));
Map<String, Set<String>> countryLanguageSets = locales.collect(
Collectors.toMap( Locale::getDisplayCountry,l -> Set.of(l.getDisplayLanguage()),
(a, b) ->{ // union of a and b
Set<String> union = new HashSet<>(a);
union.addAll(b);
return union;
}));
2.4. 群组和分区
●static <T,K> Collector<T,?,Map<K,List<T>>> groupingBy(Function<? super T,? extends K>classifier)
●static <T,K> Collector<T,?,Concurrenthap<K,List<T>>> groupingByConcurrent(Function<? superT,? extends K> classifier)
产生一个收集器,它会产生一个映射表或并发映射表,其键是将classifier 应用于所有收集到的元素上所产生的 结果,而值是由具有相同键的元素构成的一个个列表。
Map<Employee.Status, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus))
2.4.1. 多级分组
Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60) {
return "老年";
} else if(e.getAge() >= 35) {
return "中年";
} else {
return "成年";
}
})));
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(map);
System.out.println(s);
2.4.2. static <T> Collector<T,?,Map<Boolean,List<>>> partitioningBy(Predicate<? super T>predicate)
产生一个收集器,它会产生一个映射表,其键是true/false,而值是由满足/不满足断言的元素构成的列表。
Map<Boolean, List<Employee>> map = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
2.5. 连接字符串
- static Collector<CharSequence,?,String> joining()
- static Collector<CharSequence,?,String> joining(CharSequence delimiter)
- static Collector<CharSequence,?,String joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix)
String s = emps.stream()
.map(Employee::getName)
.collect(Collectors.joining("','" , "('", "')"));
2.6. 计算
Int|Long|Double Summarystatistics
通过它们可以获得将mapper 应用于每个元素后所产生的结果的数量、总和、平均值、最大值和最小值。
● static <T>Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
● static <T>Collector<T,?,LongSummaryStatistics> summarizingLong(ToLongFunction<? super T> mapper
● static <T> Collector<T,?,DoubleSummaryStatistics> summarizingDouble(TooubleFunction<? super T> apper)
IntSummaryStatistics 8 LongSummaryStatistics 8 DoubleSummaryStatistics 8
●long getCount()
产生汇总后的元素的个数。
●(int|Longldouble) getSum()
● double getAverage()
产生汇总后的元素的总和或平均值,或者在没有任何元素时返回0
●(int| longldouble) getMax()
●(int|Llongl double) getMin()
产生汇总后的元素的最大值和最小值,或者在没有任何元素时,产生(Integer| Longl Double). (MAX|MIN)VALUE。
summingInt
Integer 对流中元素的整数属性求和 summingDouble
int total =list.stream().collect(Collectors.summingInt(Employee::getSalary));
averagingInt
Double 计算流中元素Integer属性的平均值 averagingDouble
double avg = list.stream().collect(Collectors.averagingInt(Employee::getSalary));
3. 下游收集
groupingBy方法会产生一个映射表,它的每个值都是一个列表。如果想要以某种方式来处理这些列表,就需要提供一个"下游收集器"。例如,如果想要获得集而不是列表
Map<String,Set<Locale>> countryToLocaleSet = locales.collect(
groupingBy(Locale::getCountry,toSet()));
3.1. counting
Map<String, Long> countryToLocaleCounts = locales.collect(
groupingBy(Locale::getCountry,counting()));
3.2. summing(Int|Long|Double)
会接受一个函数作为引元,将该函数应用到下游元素中,并产生它们的和。
例如∶可以计算城市流中每个州的人口总和。
Map<String, Integer> stateToCityPopulation = cities.collect(
groupingBy(City::getState, summingInt(City::getPopulation)));
3.3. maxBy 和 minBy
会接受一个比较器,并分别产生下游元素中的最大值和最小值。
例如∶可以产生每个州中最大的城市。
Map<String,Optional<City>> stateToLargestCity = cities.collect(
groupingBy(City::getState,
maxBy(Comparator.comparing(City::getPopulation))))
3.4. mapping
它会将一个函数应用于收集到的每个元素。并将结果传递给下游收集器。
Map<Character, Set<Integer>> stringLengthsByStartingletter = strings.collect(
groupingBy(s-> s.charAt(0),
mapping(String::length, toSet())));
Map<String, Set<String>> countryToLanguages = locales.collect(
groupingBy(Locale::getDisplayCountry,
mapping(Locale::getDisplayLanguage, toSet()))
3.5. filtering收集器会将一个过滤器应用到每个组上
Map<String, Set<City>> largecCitiesByState= cities.collect(
groupingBy(City::;getState,
filtering(C->C.getPopulation()>50000,
toSet()));
3.6. 如果群组和映射函数的返回值为 int、long 或 double,那么可以将元素收集到汇总统计对象中
然后,可以从每个组的汇总统计对象中获取这些函数值的总和、数量、平均值、最小值和最大值。
Map<String,IntSummaryStatistics> stateToCityPopulationSummary = cities.collect(
groupingBy(City::getState, summarizingInt(City::getPopulation)));
4. collectingAndThen
先进行结果集的收集,然后将收集到的结果集进行下一步的处理
static <T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,Function<R,RR>finisher)
ArrayList<TestStreamModel> collect = list.stream().collect(collectingAndThen(
toCollection(() -> new TreeSet<>(Comparator.comparing(TestStreamModel::getName))),
ArrayList::new)
);
ArrayList<TestStreamModel> collect1 = list.stream().collect(collectingAndThen(
toCollection(HashSet::new),
ArrayList::new)
);
5. 约简
reduce方法是一种用于从流中计算某个值的通用机制,其最简单的形式将接受一个二元函数并从前两个元素开始持续应用它
List<Inteqer> values = ...;
Optional<Integer> sum = values.stream().reduce((x,y)-> x + y)
计算v1+v2+v3,+…,其中v;是流中的元素。如果流为空,那么该方法会返回一个0ptional
5.1. api
reduce(T iden, BinaryOperator b):可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b):可以将流中元素反复结合起来,得到一个值。返回Optional<T>
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0, (x, y) -> x + y);
Optional<Double> op = emps.stream()
.map(Employee::getSalary)
.reduce(Double::sum);