Java Stream中自定義Collector實現(xiàn)復雜數(shù)據(jù)收集的方法
1. Collector接口的作用
Collector
接口定義了數(shù)據(jù)收集、轉(zhuǎn)換和聚合的基本操作,使得從Stream中收集到特定的數(shù)據(jù)結構或執(zhí)行復雜的聚合操作成為可能。Collector
接口為Stream操作提供了一個終止方法,將Stream的處理結果收集到一個特定的容器中。
2. Collector接口的組成
Collector
接口包含以下五個主要方法:
supplier():返回一個新的結果容器的
Supplier
。這個方法用于創(chuàng)建用于存儲收集結果的容器。accumulator():接收一個結果容器和一個流中的元素,將元素添加到結果容器中。這是累積元素的核心方法,用于將流中的元素逐個添加到結果容器中。
combiner():接收兩個結果容器,合并它們。在并行流處理中,如果有多個結果容器被生成,則使用
combiner()
方法將它們合并為一個容器。finisher():接收一個結果容器,返回最終結果。這個方法通常用于將結果容器轉(zhuǎn)換為最終想要的形式,例如,對容器中的元素進行排序或過濾。
characteristics():返回一個不可變的Set,包含收集器的特性。這些特性用于優(yōu)化流處理過程,如并行流處理或結果的無序性。
3. Collector接口的工作原理
Collector
接口的工作原理基于上述五個方法的協(xié)作。先通過supplier()
方法創(chuàng)建一個新的結果容器。然后,遍歷Stream中的每個元素,使用accumulator()
方法將元素添加到結果容器中。在并行流處理中,如果有多個結果容器被生成,則使用combiner()
方法將它們合并為一個容器。最后,通過finisher()
方法將結果容器轉(zhuǎn)換為最終想要的形式,并返回。
4. Collector的預定義實現(xiàn)Collectors
Collectors可以看做是Collector接口的實現(xiàn)工廠,提供了多個用于數(shù)據(jù)收集、轉(zhuǎn)換和聚合的預定義收集器,如toList()、toSet()、toMap()、joining()、counting()、summingInt()、averagingInt()等。這些收集器利用Collector接口實現(xiàn),使得從Stream中收集數(shù)據(jù)變得更為方便和高效。
List<String> list = Stream.of("a", "b", "c") .collect(Collectors.toList()); Map<Character, List<String>> grouped = Stream.of("a", "b", "c") .collect(Collectors.groupingBy(s -> s.charAt(0))); String joined = Stream.of("a", "b", "c") .collect(Collectors.joining(", "));
如,toList()收集器通過調(diào)用new ArrayList<>()來創(chuàng)建一個新的結果容器,并使用accumulator()方法將流中的元素添加到結果容器中。toMap()收集器則創(chuàng)建一個新的HashMap,并使用提供的鍵函數(shù)和值函數(shù)將元素映射到Map的鍵和值上。
5. 自定義Collector的使用場景
通過實現(xiàn)Collector
接口來自定義復雜的收集器,以滿足特定的數(shù)據(jù)處理需求。自定義Collector
時,要實現(xiàn)上述五個方法,并定義如何收集、轉(zhuǎn)換和聚合數(shù)據(jù)。
如,自定義Collector
對Person
對象進行排序,并根據(jù)特定條件進行分組:
public static class CustomCollector<T> implements Collector<Person, List<Person>, Map<String, List<Person>>> { @Override public Supplier<List<Person>> supplier() { return ArrayList::new; } @Override public BiConsumer<List<Person>, Person> accumulator() { return (list, person) -> list.add(person); } @Override public BinaryOperator<List<Person>> combiner() { return (list1, list2) -> { list1.addAll(list2); return list1; }; } @Override public Function<List<Person>, Map<String, List<Person>>> finisher() { return list -> { Map<String, List<Person>> result = new HashMap<>(); // 自定義排序規(guī)則 list.sort((p1, p2) -> { if (p1.age != null && p2.age != null) { return p1.age.compareTo(p2.age); } else if (p1.age != null) { return -1; } else if (p2.age != null) { return 1; } else { return p1.name.compareTo(p2.name); } }); // 自定義分組規(guī)則 for (Person person : list) { if (result.containsKey(person.name.substring(0, 2))) { result.get(person.name.substring(0, 2)).add(person); } else { List<Person> group = new ArrayList<>(); group.add(person); result.put(person.name.substring(0, 2), group); } } return result; }; } @Override public Set<Collector.Characteristics> characteristics() { return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH); } }
自定義收集、轉(zhuǎn)換和聚合Person
對象的邏輯。使用自定義的排序和分組規(guī)則,根據(jù)姓名和年齡將Person
對象分組并排序,最終返回Map<String, List<Person>>
。
通過自定義Collector
,創(chuàng)建特定的收集器,而滿足復雜的數(shù)據(jù)處理需求。
使用方法:
import java.util.*; public class CustomCollectorDemo { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 25), new Person("Bob", 23), new Person("Charlie", 28), new Person("David", 25), new Person("Eva", 23), new Person("Frank", 28) ); Map<String, List<Person>> result = people.stream() .collect(new CustomCollector<>()); System.out.println(result); } static class Person { String name; Integer age; ... } }
到此這篇關于Java Stream中自定義Collector實現(xiàn)復雜數(shù)據(jù)收集的方法的文章就介紹到這了,更多相關Java Stream自定義Collector數(shù)據(jù)收集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SSH框架網(wǎng)上商城項目第15戰(zhàn)之線程、定時器同步首頁數(shù)據(jù)
這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第15戰(zhàn)之線程、定時器同步首頁數(shù)據(jù),感興趣的小伙伴們可以參考一下2016-06-06利用Mybatis?Plus實現(xiàn)一個SQL攔截器
SQL攔截器是一種用于攔截和修改Mybatis執(zhí)行的SQL語句的工具,通過使用SQL攔截器,開發(fā)人員可以在執(zhí)行SQL語句之前或之后對其進行修改或記錄,本文就來借助一下Mybatis-Plus實現(xiàn)一個SQL攔截器吧2023-05-05Lombok中@EqualsAndHashCode注解的使用及說明
這篇文章主要介紹了Lombok中@EqualsAndHashCode注解的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03解決springboot+activemq啟動報注解錯誤的問題
這篇文章主要介紹了解決springboot+activemq啟動報注解錯誤的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07