Stream流处理list分组方法

    xiaoxiao2023-11-03  159

    工作中经常碰到list去重的问题,现在我简单分享一下我的处理方式。

    @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor class Student { /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 性别,0和1 */ private Integer sex; /** * 描述 */ private String desc; /** * 班级id,1.2.3... */ private Integer classId; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Student)) return false; Student student = (Student) o; return getName().equals(student.getName()); } @Override public int hashCode() { return Objects.hash(getName()); } } class TestList{ public static void main(String[] args) { List<Student> studentList = new ArrayList<>(); studentList.add(new Student("张飞",48,0,"皮肤有点黑",2)); studentList.add(new Student("关羽",50,0,"关羽字云长",2)); studentList.add(new Student("吕布",51,0,"吕布字奉先",4)); studentList.add(new Student("张飞",48,0,"张飞字翼德",2)); studentList.add(new Student("张飞",22,0,"张飞字翼德",3)); studentList.add(new Student("赵云",48,0,"赵云字子龙",2)); studentList.add(new Student("马超",25,0,"马超子孟起",2)); studentList.add(new Student("黄忠",48,0,"黄忠字汉升",2)); studentList.add(new Student("夏侯渊",26,0,"夏侯渊字妙才",1)); studentList.add(new Student("夏侯惇",68,0,"夏侯惇字元让",1)); studentList.add(new Student("曹仁",48,0,"曹仁不知道",1)); studentList.add(new Student("甘宁",61,0,"甘宁字兴霸",3)); studentList.add(new Student("周泰",48,0,"周泰不知道",3)); studentList.add(new Student("诸葛亮",15,0,"孔明",2)); studentList.add(new Student("周瑜",64,0,"不知道",3)); studentList.add(new Student("司马懿",578,0,"仲达",1)); studentList.add(new Student("司马懿",46,0,"仲达",1)); studentList.add(new Student("张飞",58,0,"假张飞",2)); studentList.add(new Student("赵云",57,0,"高达赵云",5)); studentList.add(new Student("吕布",57,0,"皮肤有点黑",4)); studentList.add(new Student("貂蝉",18,0,"沉鱼落雁",4)); studentList.add(new Student("甄姬",18,0,"闭月羞花",2)); //手工创建一些数据测试 //情形一,名字相同的全部当做重复 Set<Student> nameSet = new HashSet<>(); for (Student s:studentList) { nameSet.add(s); } for (Student s:nameSet) { System.out.println(s); } } }

    这种利用set去重,代码也不算多,但是并不能实现复杂的情形,下面介绍java8的stream流处理

    Map<String,List<Student>> map = studentList.stream().collect(Collectors.groupingBy(Student::getName)); MapUtils.verbosePrint(System.out,"打印",map);

    结果 上面利用到collect收集器里面的分组方法,用过name分组得到map,这样子去重复就很简单。 在重写过hashCode和equals方法直接用下面的更简单,直接利用distinct,就像mysql里面的差不多

    studentList.stream().distinct().collect(Collectors.toList()).stream().forEach(System.out::println);

    现在说一下稍微复杂的业务,根据名字和class分组,也就是说名字和班级都相同的才算重复 这种情况重新封一个对象利用set也是挺方便的

    我这里介绍一下双重分组

    Map<String,Map<Integer,List<Student>>> map1 = studentList.stream().collect(Collectors.groupingBy(Student::getName,Collectors.groupingBy(Student::getClassId))); MapUtils.verbosePrint(System.out,"打印",map1);

    结果

    具体的分组我并没有做,这种分组得到map再来处理也挺麻烦的,各种工具包也有挺多的分组去重的方法。 这里只是说了一下java8stream的方便,代码确实优雅很多。

    此外stream流提供了多种其他的方法,比如map,filter等,这里就不多说了。

    原创文章分享请注明出处

    最新回复(0)