Collectors
Collectors类API
<code class="java">1. public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory); 2. public static <T> Collector<T, ?, List<T>> toList(); 3. public static <T> Collector<T, ?, Set<T>> toSet(); 4. public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) ; 5. public static <T, K, U> Collector<T, ?, Map<K,U>> toMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction); 6. public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier); 7. public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) ; 8. public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream) ; 9. public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream); 10. public static Collector<CharSequence, ?, String> joining(); 11. public static Collector<CharSequence, ?, String> joining(CharSequence delimiter); 12. public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) ; 13. public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream)
<code class="java">@Getter @Setter @ToString @Builder public class Student { private Long id; private String name; private Integer age; private String address; }
toCollection
办法
Collectors类给了toList()
和toSet()
办法,默认的是ArrayList
和HashSet
,所以要想应用其余的类型的汇合就能够应用这个办法,例如应用LinkedList
<code class="java">public class CollectorsTest { public static void main(String[] args) { } private List<Student> list = new ArrayList<>(); @Before public void init(){ Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build(); Student student2 = Student.builder().id(2L).name("李四").age(21).address("上海").build(); Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build(); Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build(); Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build(); list = Stream.of( student4,student5,student1, student2, student3).collect(Collectors.toList()); } @Test public void testCollection(){ System.out.println("list : "); System.out.println(JSON.toJSONString(list)); LinkedList<Student> linkedList = list.stream().collect(Collectors.toCollection(LinkedList::new)); System.out.println("linkedList : "); System.out.println(JSON.toJSONString(linkedList)); } }
<code class="java">list : [{"address":"北京","age":20,"id":1,"name":"张三"},{"address":"上海","age":21,"id":2,"name":"李四"},{"address":"广州","age":22,"id":3,"name":"王五"},{"address":"重庆","age":23,"id":4,"name":"赵六"},{"address":"武汉","age":24,"id":5,"name":"钱七"}] linkedList : [{"address":"北京","age":20,"id":1,"name":"张三"},{"address":"上海","age":21,"id":2,"name":"李四"},{"address":"广州","age":22,"id":3,"name":"王五"},{"address":"重庆","age":23,"id":4,"name":"赵六"},{"address":"武汉","age":24,"id":5,"name":"钱七"}]
toList()
办法
这个最常见和罕用的办法
<code class="java">List<Student> list = Stream.of( student4,student5,student1, student2, student3).collect(Collectors.toList());
toSet()
办法
这个也是最常见和罕用的办法
<code class="java">Set<Student> set = Stream.of(student4, student5, student1, student2, student3).collect(Collectors.toSet());
toMap()
办法
toMap()
起码接管两个参数
<code class="java"> @Test public void testToMap(){ Map<Long, Student> towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity())); System.out.println(JSON.toJSONString(towParamMap)); }
Collectors.toMap(Student::getId, Function.identity())
这个办法碰到反复的key会抛出异样,把张三和李四的id改成一样,再次运行机会抛出异样
<code class="java"> @Before public void init(){ Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build(); Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build(); Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build(); Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build(); Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build(); list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList()); } @Test public void testToMap(){ Map<Long, Student> towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity())); System.out.println(JSON.toJSONString(towParamMap)); }
<code class="java">java.lang.IllegalStateException: Duplicate key Student(id=1, name=张三, age=20, address=北京)
所以应用这个办法时须要留神,这时能够通过第三个参数来解决反复key的问题
<code class="java"> @Before public void init(){ Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build(); Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build(); Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build(); Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build(); Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build(); list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList()); } @Test public void testToMap(){ Map<Long, Student> threeParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a,b) -> b)); System.out.println(JSON.toJSONString(threeParamMap)); }
后果为
<code class="java">{1:{"address":"上海","age":21,"id":1,"name":"李四"},3:{"address":"广州","age":22,"id":3,"name":"王五"},4:{"address":"重庆","age":23,"id":4,"name":"赵六"},5:{"address":"武汉","age":24,"id":5,"name":"钱七"}}
能够看到李四笼罩了张三,所以理论中应用时也要留神数据抉择.留神一下这个函数(a,b) -> b
也能够从新本人定义一个合并的函数BinaryOperator<U> mergeFunction
来解决反复数据
还有四个参数的办法能够不应用默认的HashMap
而应用其余的容器,例如TreeMap
<code class="java">Map<Long, String> fourParamMap = list.stream().collect(Collectors.toMap(Student::getId, student -> student.getName(), (a,b) -> b, TreeMap::new)); System.out.println(JSON.toJSONString(fourParamMap));
后果
<code class="java">{1:"李四",3:"王五",4:"赵六",5:"钱七"}
groupingBy()
办法
Collectors类 groupingBy
办法
-
一个参数的办法
一个参数的办法,还是调用的两个参数的重载办法,第二个参数默认调用
toList()
办法<code class="java">public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) { return groupingBy(classifier, toList()); }
示例:
<code class="java">public class GroupingByTest { public static void main(String[] args) { List<Student> students = new ArrayList<>(); Student student = new Student(); student.setId(1L); student.setName("小明"); students.add(student); Student student2 = new Student(); student2.setId(2L); student2.setName("小红"); students.add(student2); Map<Long, List<Student>> collect = students.stream().collect(Collectors.groupingBy(s -> { return s.getId(); })); System.out.println(JSON.toJSONString(collect)); } }
后果
<code class="java">{1:[{"id":1,"name":"小明"}],2:[{"id":2,"name":"小红"}]}
groupingBy
办法参数Function<? super T, ? extends K> classifier
<code class="java">@FunctionalInterface public interface Function<T, R> { R apply(T t); }
Function
是函数式接口,接管一个参数T,返回一个后果R,示例中能够示意为上面这样的,先创立一个Function接口,再将接口当作参数传进去.
<code class="java"> Function<Student, Long> groupingByFun = s -> {return s.getId()}; Map<Long, List<Student>> collect = students.stream().collect(Collectors.groupingBy(groupingByFun ));
优化s -> {return s.getId()}
能够简化写法
<code class="java">Function<Student, Long> groupingByFun = s -> {return s.getId()}; // 能够简化成 Function<Student, Long> groupingByFun = s -> s.getId(); // 再一次简化 Function<Student, Long> groupingByFun = Student::getId;
-
两个参数的办法
<code class="java">public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream) { return groupingBy(classifier, HashMap::new, downstream); }
示例
<code class="java">Map<Long, Long> countMap = students.stream().collect(Collectors.groupingBy(Student::getId, Collectors.counting())); System.out.println(JSON.toJSONString(countMap)); // {1:1,2:1}
-
三个参数的办法
<code class="java">public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream) { }
示例
<code class="java">TreeMap<Long, Set<Student>> treeMapSet = students.stream().collect(Collectors.groupingBy(Student::getId, TreeMap::new, Collectors.toSet())); System.out.println(JSON.toJSONString(treeMapSet)); // {1:[{"id":1,"name":"小明"}],2:[{"id":2,"name":"小红"}]}
joining()
办法
总共默认了三个拼接办法
<code class="java"> @Test public void testJoin(){ String join = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining()); System.out.println(join); String join1 = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining(",")); System.out.println(join1); String join2 = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining(",","","")); System.out.println(join2); } // helloworldhellojava //hello,world,hello,java //hello,world,hello,java
从外部实现来看,还是有不一样,不带参数的办法,外部应用StringBuilder
实现
<code class="java">public static Collector<CharSequence, ?, String> joining() { return new CollectorImpl<CharSequence, StringBuilder, String>( StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString, CH_NOID); }
带参数的办法应用StringJoiner
实现
<code class="java">public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { return new CollectorImpl<>( () -> new StringJoiner(delimiter, prefix, suffix), StringJoiner::add, StringJoiner::merge, StringJoiner::toString, CH_NOID); }
mapping()
办法
mapping
简略用法,mapping
最简略的用法能够和map办法一样收集某一个字段的值,大部分状况能够和groupingBy
,配合应用,例如分组之后只想取某一个字段的值,就能够应用Collectors.mapping
配合
<code class="java"> private List<Student> list = new ArrayList<>(); @Before public void init(){ Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build(); Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build(); Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build(); Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build(); Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build(); list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList()); } @Test public void testMapping(){ // 收集单个字段 List<Long> mappingList = list.stream().collect(Collectors.mapping(Student::getId, Collectors.toList())); System.out.println(JSON.toJSONString(mappingList)); // 和groupingBy配合应用 Map<Long, List<String>> mapping = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.mapping(Student::getName, Collectors.toList()))); System.out.println(JSON.toJSONString(mapping)); }
本文由博客一文多发平台 OpenWrite 公布!