Java8 Stream详解~收集(collect)
collect,收集,可以說是內(nèi)容最繁多、功能最豐富的部分了。從字面上去理解,就是把一個流收集起來,最終可以是收集成一個值也可以收集成一個新的集合。
1 歸集(toList/toSet/toMap)
因為流不存儲數(shù)據(jù),那么在流中的數(shù)據(jù)完成處理后,需要將流中的數(shù)據(jù)重新歸集到新的集合里。toList、toSet和toMap比較常用,另外還有toCollection、toConcurrentMap等復(fù)雜一些的用法。
下面用一個案例演示toList、toSet和toMap:
public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000).collect(Collectors.toMap(Person::getName, p -> p));System.out.println("toList:" + listNew);System.out.println("toSet:" + set);System.out.println("toMap:" + map);} }2 統(tǒng)計(count/averaging)
Collectors提供了一系列用于數(shù)據(jù)統(tǒng)計的靜態(tài)方法:
-
計數(shù):count
-
平均值:averagingInt、averagingLong、averagingDouble
-
最值:maxBy、minBy
-
求和:summingInt、summingLong、summingDouble
-
統(tǒng)計以上所有:summarizingInt、summarizingLong、summarizingDouble
「案例:統(tǒng)計員工人數(shù)、平均工資、工資總額、最高工資?!?/strong>
public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));// 求總數(shù)Long count = personList.stream().collect(Collectors.counting());// 求平均工資Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));// 求最高工資Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));// 求工資之和Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));// 一次性統(tǒng)計所有信息DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));System.out.println("員工總數(shù):" + count);System.out.println("員工平均工資:" + average);System.out.println("員工工資總和:" + sum);System.out.println("員工工資所有統(tǒng)計:" + collect);} }3 分組(partitioningBy/groupingBy)
-
分區(qū):將stream按條件分為兩個Map,比如員工按薪資是否高于8000分為兩部分。
-
分組:將集合分為多個Map,比如員工按性別分組。有單級分組和多級分組。
?「案例:將員工按薪資是否高于8000分為兩部分;將員工按性別和地區(qū)分組」
public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, "male", "New York"));personList.add(new Person("Jack", 7000, "male", "Washington"));personList.add(new Person("Lily", 7800, "female", "Washington"));personList.add(new Person("Anni", 8200, "female", "New York"));personList.add(new Person("Owen", 9500, "male", "New York"));personList.add(new Person("Alisa", 7900, "female", "New York"));// 將員工按薪資是否高于8000分組Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));// 將員工按性別分組Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));// 將員工先按性別分組,再按地區(qū)分組Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));System.out.println("員工按薪資是否大于8000分組情況:" + part);System.out.println("員工按性別分組情況:" + group);System.out.println("員工按性別、地區(qū):" + group2);} }4 接合(joining)
joining可以將stream中的元素用特定的連接符(沒有的話,則直接連接)連接成一個字符串。
public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));System.out.println("所有員工的姓名:" + names);List<String> list = Arrays.asList("A", "B", "C");String string = list.stream().collect(Collectors.joining("-"));System.out.println("拼接后的字符串:" + string);} }5 歸約(reducing)
Collectors類提供的reducing方法,相比于stream本身的reduce方法,增加了對自定義歸約的支持。
public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<Person>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));// 每個員工減去起征點后的薪資之和(這個例子并不嚴謹,但一時沒想到好的例子)Integer sum = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));System.out.println("員工扣稅薪資總和:" + sum);// stream的reduceOptional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum);System.out.println("員工薪資總和:" + sum2.get());} }總結(jié)
以上是生活随笔為你收集整理的Java8 Stream详解~收集(collect)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小甲鱼 OllyDbg 教程系列 (七)
- 下一篇: 反调试技术揭秘(转)