Collectors简单使用
Collectors
Collectors类API
1. public static > Collector toCollection(Supplier collectionFactory);
2. public static Collector> toList();
3. public static Collector> toSet();
4. public static Collector> toMap(Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper) ;
5. public static Collector> toMap(
Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper,
BinaryOperator mergeFunction);
6. public static > Collector toMap(
Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper,
BinaryOperator mergeFunction,
Supplier mapSupplier);
7. public static Collector>>
groupingBy(Function super T, ? extends K> classifier) ;
8. public static
Collector> groupingBy(Function super T, ? extends K> classifier,
Collector super T, A, D> downstream) ;
9. public static >
Collector groupingBy(Function super T, ? extends K> classifier,
Supplier mapFactory,
Collector super T, A, D> downstream);
10. public static Collector joining();
11. public static Collector joining(CharSequence delimiter);
12. public static Collector joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) ;
13. public static
Collector mapping(Function super T, ? extends U> mapper,
Collector super U, A, R> downstream)
@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
public class CollectorsTest {public static void main(String[] args) {
}private List 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 linkedList = list.stream().collect(Collectors.toCollection(LinkedList::new));
System.out.println("linkedList : ");
System.out.println(JSON.toJSONString(linkedList));
}
}
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()
方法这个最常见和常用的方法
List list = Stream.of( student4,student5,student1, student2, student3).collect(Collectors.toList());
toSet()
方法这个也是最常见和常用的方法
Set set = Stream.of(student4, student5, student1, student2, student3).collect(Collectors.toSet());
toMap()
方法toMap()
最少接收两个参数@Test
public void testToMap(){
Map towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
System.out.println(JSON.toJSONString(towParamMap));
}
Collectors.toMap(Student::getId, Function.identity())
这个方法碰到重复的key会抛出异常,把张三和李四的id改成一样,再次运行机会抛出异常@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 towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
System.out.println(JSON.toJSONString(towParamMap));
}
java.lang.IllegalStateException: Duplicate key Student(id=1, name=张三, age=20, address=北京)
所以使用这个方法时需要注意,这时可以通过第三个参数来解决重复key的问题
@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 threeParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a,b) -> b));
System.out.println(JSON.toJSONString(threeParamMap));
}
结果为
{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 mergeFunction
来处理重复数据还有四个参数的方法可以不使用默认的
HashMap
而使用其他的容器,例如TreeMap
Map fourParamMap = list.stream().collect(Collectors.toMap(Student::getId, student -> student.getName(), (a,b) -> b, TreeMap::new));
System.out.println(JSON.toJSONString(fourParamMap));
结果
{1:"李四",3:"王五",4:"赵六",5:"钱七"}
groupingBy()
方法【Collectors简单使用】Collectors类
groupingBy
方法- 一个参数的方法
一个参数的方法,还是调用的两个参数的重载方法,第二个参数默认调用toList()
方法
public static
Collector >> groupingBy(Function super T, ? extends K> classifier) { return groupingBy(classifier, toList()); }
示例:
public class GroupingByTest {public static void main(String[] args) { List 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
collect = students.stream().collect(Collectors.groupingBy(s -> { return s.getId(); })); System.out.println(JSON.toJSONString(collect)); } }
结果
{1:[{"id":1,"name":"小明"}],2:[{"id":2,"name":"小红"}]}
groupingBy
方法参数Function super T, ? extends K> classifier
@FunctionalInterface public interface Function
{ R apply(T t); }
Function
是函数式接口,接收一个参数T,返回一个结果R,示例中可以表示为下面这样的,先创建一个Function接口,再将接口当作参数传进去.Function groupingByFun = s -> {return s.getId()};
Map collect = students.stream().collect(Collectors.groupingBy(groupingByFun
));
优化
s -> {return s.getId()}
可以简化写法Function groupingByFun = s -> {return s.getId()};
// 可以简化成
Function groupingByFun = s ->s.getId();
// 再一次简化
Function groupingByFun = Student::getId;
- 两个参数的方法
public static
Collector > groupingBy(Function super T, ? extends K> classifier, Collector super T, A, D> downstream) { return groupingBy(classifier, HashMap::new, downstream); }
示例
Map
countMap = students.stream().collect(Collectors.groupingBy(Student::getId, Collectors.counting())); System.out.println(JSON.toJSONString(countMap)); // {1:1,2:1}
- 三个参数的方法
public static
> Collector groupingBy(Function super T, ? extends K> classifier, Supplier mapFactory, Collector super T, A, D> downstream) {}
示例
TreeMap
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()
方法总共默认了三个拼接方法
@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
实现public static Collector joining() {
return new CollectorImpl(
StringBuilder::new, StringBuilder::append,
(r1, r2) -> { r1.append(r2);
return r1;
},
StringBuilder::toString, CH_NOID);
}
带参数的方法使用
StringJoiner
实现public static Collector 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
配合private List 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 mappingList = list.stream().collect(Collectors.mapping(Student::getId, Collectors.toList()));
System.out.println(JSON.toJSONString(mappingList));
// 和groupingBy配合使用
Map mapping = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.mapping(Student::getName, Collectors.toList())));
System.out.println(JSON.toJSONString(mapping));
}
本文由博客一文多发平台 OpenWrite 发布!
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- 科学养胃,别被忽悠,其实真的很简单
- opencv|opencv C++模板匹配的简单实现
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件