一文掌握 Java8 Stream 中 Collectors 的 24 個操作

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你好,我是看山。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Java8 應該算是業界主版本了,版本中重要性很高的一個更新是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Stream","attrs":{}}],"attrs":{}},{"type":"text","text":"流處理。關於流處理內容比較多,本文主要是說一下","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Stream","attrs":{}}],"attrs":{}},{"type":"text","text":"中的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Collectors","attrs":{}}],"attrs":{}},{"type":"text","text":"工具類的使用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Collectors","attrs":{}}],"attrs":{}},{"type":"text","text":"是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.util.stream","attrs":{}}],"attrs":{}},{"type":"text","text":"包下的一個工具類,其中各個方法的返回值可以作爲","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.util.stream.Stream#collect","attrs":{}}],"attrs":{}},{"type":"text","text":"的入參,實現對隊列的各種操作,包括:分組、聚合等。官方文檔給出一些例子:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Implementations of {@link Collector} that implement various useful reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc.","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"The following are examples of using the predefined collectors to perform common mutable reduction tasks:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// Accumulate names into a List\nList list = people.stream().map(Person::getName).collect(Collectors.toList());\n\n// Accumulate names into a TreeSet\nSet set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));\n\n// Convert elements to strings and concatenate them, separated by commas\nString joined = things.stream()\n .map(Object::toString)\n .collect(Collectors.joining(\", \"));\n\n// Compute sum of salaries of employee\nint total = employees.stream()\n .collect(Collectors.summingInt(Employee::getSalary)));\n\n// Group employees by department\nMap> byDept = employees.stream()\n .collect(Collectors.groupingBy(Employee::getDepartment));\n\n// Compute sum of salaries by department\nMap totalByDept = employees.stream()\n .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.summingInt(Employee::getSalary)));\n\n// Partition students into passing and failing\nMap> passingFailing = students.stream()\n .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));\n","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"定義示例數據","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"先定義待操作對象,一個萬能的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"類(用到了 lombok):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"@Data\n@AllArgsConstructor\npublic class Student {\n private String id;\n private String name;\n private LocalDate birthday;\n private int age;\n private double score;\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後定義一組測試數據:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"final List students = Lists.newArrayList();\nstudents.add(new Student(\"1\", \"張三\", LocalDate.of(2009, Month.JANUARY, 1), 12, 12.123));\nstudents.add(new Student(\"2\", \"李四\", LocalDate.of(2010, Month.FEBRUARY, 2), 11, 22.123));\nstudents.add(new Student(\"3\", \"王五\", LocalDate.of(2011, Month.MARCH, 3), 10, 32.123));\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"數據統計","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"元素數量:counting","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個比較簡單,就是統計聚合結果的元素數量:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 3\nstudents.stream().collect(Collectors.counting())\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"平均值:averagingDouble、averagingInt、averagingLong","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這幾個方法是計算聚合元素的平均值,區別是輸入參數需要是對應的類型。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,求學生的分數平均值,因爲分數是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"double","attrs":{}}],"attrs":{}},{"type":"text","text":"類型,所以在不轉類型的情況下,需要使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"averagingDouble","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 22.123\nstudents.stream().collect(Collectors.averagingDouble(Student::getScore))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果考慮轉換精度,也是可以實現:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 22.0\nstudents.stream().collect(Collectors.averagingInt(s -> (int)s.getScore()))\n// 22.0\nstudents.stream().collect(Collectors.averagingLong(s -> (long)s.getScore()))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果是求學生的平均年齡,因爲年齡是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"int","attrs":{}}],"attrs":{}},{"type":"text","text":"類型,就可以隨意使用任何一個函數了:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 11.0\nstudents.stream().collect(Collectors.averagingInt(Student::getAge))\n// 11.0\nstudents.stream().collect(Collectors.averagingDouble(Student::getAge))\n// 11.0\nstudents.stream().collect(Collectors.averagingLong(Student::getAge))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意:這三個方法的返回值都是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Double","attrs":{}}],"attrs":{}},{"type":"text","text":"類型。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"和:summingDouble、summingInt、summingLong","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這三個方法和上面的平均值方法類似,也是需要注意元素的類型,在需要類型轉換時,需要強制轉換:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 66\nstudents.stream().collect(Collectors.summingInt(s -> (int)s.getScore()))\n// 66.369\nstudents.stream().collect(Collectors.summingDouble(Student::getScore))\n// 66\nstudents.stream().collect(Collectors.summingLong(s -> (long)s.getScore()))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是對於不需要強制轉換的類型,可以隨意使用任何一個函數:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 33\nstudents.stream().collect(Collectors.summingInt(Student::getAge))\n// 33.0\nstudents.stream().collect(Collectors.summingDouble(Student::getAge))\n// 33\nstudents.stream().collect(Collectors.summingLong(Student::getAge))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意:這三個方法返回值和平均值的三個方法不一樣,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summingDouble","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Double","attrs":{}}],"attrs":{}},{"type":"text","text":"類型、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summingInt","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Integer","attrs":{}}],"attrs":{}},{"type":"text","text":"類型,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summingLong","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Long","attrs":{}}],"attrs":{}},{"type":"text","text":"類型。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"最大值/最小值元素:maxBy、minBy","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顧名思義,這兩個函數就是求聚合元素中指定比較器中的最大/最小元素。比如,求年齡最大/最小的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"對象:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// Optional[Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)],注意返回類型是Optional\nstudents.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)))\n// Optional[Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)],注意返回類型是Optional\nstudents.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從源碼可以看出來,這兩個方法算是作者給的福利,用於完善數據統計的結果。內部都是封裝了","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"reducing","attrs":{}}],"attrs":{}},{"type":"text","text":"方法和","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"BinaryOperator","attrs":{}}],"attrs":{}},{"type":"text","text":"工具類,這些下面會講到。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"public static Collector> maxBy(Comparator super T> comparator) {\n return reducing(BinaryOperator.maxBy(comparator));\n}\n\npublic static Collector> minBy(Comparator super T> comparator) {\n return reducing(BinaryOperator.minBy(comparator));\n}\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"統計結果:summarizingDouble、summarizingInt、summarizingLong","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然是數據操作,基本上逃不出計數、求平局、求和、最大、最小這幾個,所以作者也是很貼心的實現了一組聚合的數據統計方法。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這組方法與求和、求平均的方法類似,都需要注意方法類型。比如,按照分數統計的話,需要進行類型轉換:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// IntSummaryStatistics{count=3, sum=66, min=12, average=22.000000, max=32}\nstudents.stream().collect(Collectors.summarizingInt(s -> (int) s.getScore()))\n// DoubleSummaryStatistics{count=3, sum=66.369000, min=12.123000, average=22.123000, max=32.123000}\nstudents.stream().collect(Collectors.summarizingDouble(Student::getScore))\n// LongSummaryStatistics{count=3, sum=66, min=12, average=22.000000, max=32}\nstudents.stream().collect(Collectors.summarizingLong(s -> (long) s.getScore()))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果是用年齡統計的話,三個方法通用:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// IntSummaryStatistics{count=3, sum=33, min=10, average=11.000000, max=12}\nstudents.stream().collect(Collectors.summarizingInt(Student::getAge))\n// DoubleSummaryStatistics{count=3, sum=33.000000, min=10.000000, average=11.000000, max=12.000000}\nstudents.stream().collect(Collectors.summarizingDouble(Student::getAge))\n// LongSummaryStatistics{count=3, sum=33, min=10, average=11.000000, max=12}\nstudents.stream().collect(Collectors.summarizingLong(Student::getAge))\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意:這三個方法返回值不一樣,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summarizingDouble","attrs":{}}],"attrs":{}},{"type":"text","text":"返回","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DoubleSummaryStatistics","attrs":{}}],"attrs":{}},{"type":"text","text":"類型,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summarizingInt","attrs":{}}],"attrs":{}},{"type":"text","text":"返回","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"IntSummaryStatistics","attrs":{}}],"attrs":{}},{"type":"text","text":"類型,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"summarizingLong","attrs":{}}],"attrs":{}},{"type":"text","text":"返回","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"LongSummaryStatistics","attrs":{}}],"attrs":{}},{"type":"text","text":"類型。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"聚合、分組","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"聚合元素:toList、toSet、toCollection","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這幾個函數比較簡單,是將聚合之後的元素,重新封裝到隊列中,然後返回。比如,得到所有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"的 ID 列表,只需要根據需要的結果類型使用不同的方法即可:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// List: [1, 2, 3]\nfinal List idList = students.stream().map(Student::getId).collect(Collectors.toList());\n// Set: [1, 2, 3]\nfinal Set idSet = students.stream().map(Student::getId).collect(Collectors.toSet());\n// TreeSet: [1, 2, 3]\nfinal Collection idTreeSet = students.stream().map(Student::getId).collect(Collectors.toCollection(TreeSet::new));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toList","attrs":{}}],"attrs":{}},{"type":"text","text":"方法返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"List","attrs":{}}],"attrs":{}},{"type":"text","text":"子類,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toSet","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Set","attrs":{}}],"attrs":{}},{"type":"text","text":"子類,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toCollection","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Collection","attrs":{}}],"attrs":{}},{"type":"text","text":"子類。我們都知道,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Collection","attrs":{}}],"attrs":{}},{"type":"text","text":"的子類包括","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"List","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Set","attrs":{}}],"attrs":{}},{"type":"text","text":"等衆多子類,所以","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toCollection","attrs":{}}],"attrs":{}},{"type":"text","text":"更加靈活。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"聚合元素:toMap、toConcurrentMap","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這兩個方法的作用是將聚合元素,重新組裝爲","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Map","attrs":{}}],"attrs":{}},{"type":"text","text":"結構,也就是 k-v 結構。兩者用法一樣,區別是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Map","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toConcurrentMap","attrs":{}}],"attrs":{}},{"type":"text","text":"返回","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ConcurrentMap","attrs":{}}],"attrs":{}},{"type":"text","text":",也就是說,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toConcurrentMap","attrs":{}}],"attrs":{}},{"type":"text","text":"返回的是線程安全的 Map 結構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,我們需要聚合","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"的 id:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123), 2=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 3=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)}\nfinal Map map11 = students.stream()\n .collect(Collectors.toMap(Student::getId, Function.identity()));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,如果 id 有重複的,會拋出","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.lang.IllegalStateException: Duplicate key","attrs":{}}],"attrs":{}},{"type":"text","text":"異常,所以,爲了保險起見,我們需要藉助","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"另一個重載方法:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123), 2=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 3=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)}\nfinal Map map2 = students.stream()\n .collect(Collectors.toMap(Student::getId, Function.identity(), (x, y) -> x));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"有不同的重載方法,可以實現比較複雜的邏輯。比如,我們需要得到根據 id 分組的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"的姓名:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=張三, 2=李四, 3=王五}\nfinal Map map3 = students.stream()\n .collect(Collectors.toMap(Student::getId, Student::getName, (x, y) -> x));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,我們需要得到相同年齡得分最高的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"對象集合:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {10=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123), 11=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 12=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)}\nfinal Map map5 = students.stream()\n .collect(Collectors.toMap(Student::getAge, Function.identity(), BinaryOperator.maxBy(Comparator.comparing(Student::getScore))));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"可玩性很高。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"分組:groupingBy、groupingByConcurrent","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"都是將聚合元素進行分組,區別是,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"結果是 1:1 的 k-v 結構,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"的結果是 1:n 的 k-v 結構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,我們對","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"的年齡分組:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// List: {10=[Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)], 11=[Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123)], 12=[Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)]}\nfinal Map> map1 = students.stream().collect(Collectors.groupingBy(Student::getAge));\n// Set: {10=[Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)], 11=[Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123)], 12=[Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)]}\nfinal Map> map12 = students.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.toSet()));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"也是分組,是不是也能夠實現與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"類似的功能,比如,根據 id 分組的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123), 2=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 3=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)}\nfinal Map map3 = students.stream()\n .collect(Collectors.groupingBy(Student::getId, Collectors.collectingAndThen(Collectors.toList(), list -> list.get(0))));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了對比,把","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"toMap","attrs":{}}],"attrs":{}},{"type":"text","text":"的寫法在放這:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123), 2=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 3=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)}\nfinal Map map2 = students.stream()\n .collect(Collectors.toMap(Student::getId, Function.identity(), (x, y) -> x));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果想要得的線程安全的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Map","attrs":{}}],"attrs":{}},{"type":"text","text":",可以使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingByConcurrent","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"分組:partitioningBy","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"partitioningBy","attrs":{}}],"attrs":{}},{"type":"text","text":"與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"的區別在於,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"partitioningBy","attrs":{}}],"attrs":{}},{"type":"text","text":"藉助","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Predicate","attrs":{}}],"attrs":{}},{"type":"text","text":"斷言,可以將集合元素分爲","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"true","attrs":{}}],"attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"false","attrs":{}}],"attrs":{}},{"type":"text","text":"兩部分。比如,按照年齡是否大於 11 分組:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// List: {false=[Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)], true=[Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)]}\nfinal Map> map6 = students.stream().collect(Collectors.partitioningBy(s -> s.getAge() > 11));\n// Set: {false=[Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123), Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123)], true=[Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123)]}\nfinal Map> map7 = students.stream().collect(Collectors.partitioningBy(s -> s.getAge() > 11, Collectors.toSet()));\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"鏈接數據:joining","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個方法對","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"String","attrs":{}}],"attrs":{}},{"type":"text","text":"類型的元素進行聚合,拼接成一個字符串返回,作用與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.lang.String#join","attrs":{}}],"attrs":{}},{"type":"text","text":"類似,提供了 3 個不同重載方法,可以實現不同的需要。比如:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// javagosql\nStream.of(\"java\", \"go\", \"sql\").collect(Collectors.joining());\n// java, go, sql\nStream.of(\"java\", \"go\", \"sql\").collect(Collectors.joining(\", \"));\n// 【java, go, sql】\nStream.of(\"java\", \"go\", \"sql\").collect(Collectors.joining(\", \", \"【\", \"】\"));\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"操作鏈:collectingAndThen","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個方法在","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"的例子中出現過,它是先對集合進行一次聚合操作,然後通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Function","attrs":{}}],"attrs":{}},{"type":"text","text":"定義的函數,對聚合後的結果再次處理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"groupingBy","attrs":{}}],"attrs":{}},{"type":"text","text":"中的例子:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// {1=Student(id=1, name=張三, birthday=2009-01-01, age=12, score=12.123), 2=Student(id=2, name=李四, birthday=2010-02-02, age=11, score=22.123), 3=Student(id=3, name=王五, birthday=2011-03-03, age=10, score=32.123)}\nfinal Map map3 = students.stream()\n .collect(Collectors.groupingBy(Student::getId, Collectors.collectingAndThen(Collectors.toList(), list -> list.get(0))));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顯示將結果聚合成","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"List","attrs":{}}],"attrs":{}},{"type":"text","text":"列表,然後取列表的第 0 個元素返回,通過這種方式,實現 1:1 的 map 結構。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再來一個複雜一些的,找到聚合元素中年齡數據正確的","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Student","attrs":{}}],"attrs":{}},{"type":"text","text":"列表:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// [],結果爲空,是因爲例子中所有人的年齡都是對的\nstudents.stream()\n .collect(\n Collectors.collectingAndThen(Collectors.toList(), (\n list -> list.stream()\n .filter(s -> (LocalDate.now().getYear() - s.getBirthday().getYear()) != s.getAge())\n .collect(Collectors.toList()))\n )\n );\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個例子純粹是爲了使用","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"collectingAndThen","attrs":{}}],"attrs":{}},{"type":"text","text":"的用法,其實可以簡化爲:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"students.stream()\n .filter(s -> (LocalDate.now().getYear() - s.getBirthday().getYear()) != s.getAge())\n .collect(Collectors.toList());\n","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"操作後聚合:mapping","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"mapping","attrs":{}}],"attrs":{}},{"type":"text","text":"是先通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Function","attrs":{}}],"attrs":{}},{"type":"text","text":"函數處理數據,然後通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Collector","attrs":{}}],"attrs":{}},{"type":"text","text":"方法聚合元素。比如,獲取獲取","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"students","attrs":{}}],"attrs":{}},{"type":"text","text":"的姓名列表:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// [張三, 李四, 王五]\nstudents.stream()\n .collect(Collectors.mapping(Student::getName, Collectors.toList()));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這種計算與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.util.stream.Stream#map","attrs":{}}],"attrs":{}},{"type":"text","text":"方式類似:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// [張三, 李四, 王五]\nstudents.stream()\n .map(Student::getName)\n .collect(Collectors.toList());\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從這點上看,還是通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.util.stream.Stream#map","attrs":{}}],"attrs":{}},{"type":"text","text":"更清晰一些。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"聚合後操作:reducing","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"reducing","attrs":{}}],"attrs":{}},{"type":"text","text":"提供了 3 個重載方法:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"public static Collector> reducing(BinaryOperator op)","attrs":{}}],"attrs":{}},{"type":"text","text":":直接通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"BinaryOperator","attrs":{}}],"attrs":{}},{"type":"text","text":"操作,返回值是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Optional","attrs":{}}],"attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"public static Collector reducing(T identity, BinaryOperator op)","attrs":{}}],"attrs":{}},{"type":"text","text":":預定默認值,然後通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"BinaryOperator","attrs":{}}],"attrs":{}},{"type":"text","text":"操作","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"public static Collector reducing(U identity, Function super T, ? extends U> mapper, BinaryOperator op)","attrs":{}}],"attrs":{}},{"type":"text","text":":預定默認值,通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Function","attrs":{}}],"attrs":{}},{"type":"text","text":"操作元素,然後通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"BinaryOperator","attrs":{}}],"attrs":{}},{"type":"text","text":"操作","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,計算所有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"students","attrs":{}}],"attrs":{}},{"type":"text","text":"的得分總數:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// Optional[66.369],注意返回類型是Optional\nstudents.stream()\n .map(Student::getScore)\n .collect(Collectors.reducing(Double::sum));\n// 66.369\nstudents.stream()\n .map(Student::getScore)\n .collect(Collectors.reducing(0.0, Double::sum));\n// 66.369\nstudents.stream()\n .collect(Collectors.reducing(0.0, Student::getScore, Double::sum));\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mapping","attrs":{}}],"attrs":{}},{"type":"text","text":",","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"reducing","attrs":{}}],"attrs":{}},{"type":"text","text":"的操作與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"java.util.stream.Stream#reduce","attrs":{}}],"attrs":{}},{"type":"text","text":"方式類似:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// Optional[66.369],注意返回類型是Optional\nstudents.stream().map(Student::getScore).reduce(Double::sum);\n// 66.369\nstudents.stream().map(Student::getScore).reduce(0.0, Double::sum);\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上文說到","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"maxBy","attrs":{}}],"attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"minBy","attrs":{}}],"attrs":{}},{"type":"text","text":"時,提到這兩個函數就是通過","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"reducing","attrs":{}}],"attrs":{}},{"type":"text","text":"實現的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"mapping","attrs":{}}],"attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"reducing","attrs":{}}],"attrs":{}},{"type":"text","text":",可以參考函數式編程中 map-reduce 的概念。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"文末總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要講解了 Java8 Stream 中 Collectors 定義的 24 個方法,這種流式計算邏輯,依靠 Fork/Join 框架,性能方面有很大的優勢。如果沒有掌握這些用法,可能在後續閱讀代碼時,會很喫力,畢竟,Java8 基本上已經是業界標杆了。","attrs":{}}]},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你好,我是看山,公衆號:看山的小屋,10 年老猿,開源貢獻者。遊於碼界,戲享人生。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9e/9e305acd1cca75053c144cb28adc6061.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章