Stream流处理list分组方法

工作中经常碰到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等,这里就不多说了。

原创文章分享请注明出处

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 可以使用Java 8中的Stream)和Collectors类来根据条件对数据进行分组。可以按照以下步骤进行操作: 1. 使用Stream API将数据转换为。 2. 使用Collectors.groupingBy()方法根据条件进行分组,该方法接受一个Function参数,该函数返回一个用于分组的键。 3. 将结果存储在一个Map对象中,其中键是分组的条件,值是分组的结果。 以下是一个示例代码片段,演示如何根据条件对数据进行分组: ```java // 定义一组数据 List<Person> people = Arrays.asList( new Person("John", "New York"), new Person("Jane", "New York"), new Person("Mike", "Chicago"), new Person("Emily", "Chicago") ); // 使用和Collectors进行分组 Map<String, List<Person>> grouped = people.stream() .collect(Collectors.groupingBy(Person::getCity)); // 输出分组结果 grouped.forEach((city, group) -> { System.out.println(city + ": " + group); }); ``` 在这个示例中,我们定义了一个Person类,其中包含名称和城市属性。我们将这些人分成两组:在纽约的人和在芝加哥的人。我们使用和Collectors.groupingBy()方法按城市属性对人进行分组,并将结果存储在一个Map对象中。最后,我们打印分组结果。 ### 回答2: Stream可以通过使用Collectors.groupingBy()方法根据条件进行分组操作。Collectors.groupingBy()方法接收一个Function参数,用于指定分组的条件。这个条件可以是一个Lambda表达式或方法引用,返回的结果将作为分组的键。 例如,假设有一个包含学生对象的List集合,我们想根据学生的年级进行分组。可以使用以下代码来实现: List<Student> students = new ArrayList<>(); // 假设有一些学生对象已经添加到了students集合中 Map<String, List<Student>> groupedStudents = students.stream() .collect(Collectors.groupingBy(Student::getGrade)); 上面的代码首先使用stream()方法List集合转换为一个,然后调用collect()方法进行收集操作。在collect()方法中,使用Collectors.groupingBy()方法根据学生的getGrade()方法返回的结果进行分组。这将返回一个Map对象,其中键是分组的条件(学生的年级),值是符合条件的学生对象列表。 通过这种方式,我们可以方便地将Stream中的元素根据自定义的条件进行分组操作。无论是简单的基本类型还是更复杂的对象类型,都可以通过指定的条件进行分组。 ### 回答3: stream根据条件分组是指在使用Stream进行操作时,可以根据某种条件将中的元素按照不同的组进行分组。 在Java 8中引入了stream的特性,可以对集合进行函数式编程式的处理。使用stream对数据进行分组可以提供更灵活的筛选和分类方式,方便处理复杂的数据结构。 要实现分组,可以使用Collectors类的groupingBy方法。groupingBy方法接收一个分类函数,将中的元素按照这个分类函数分组。分类函数可以是一个Lambda表达式或方法引用。 举个例子,假设有一个包含学生信息的列表,我们想要根据学生的成绩高低来将他们分为三个组:优秀、良好和及格。我们可以使用stream根据条件分组来实现: List<Student> students = getStudentList(); // 假设获取学生列表的方法 Map<String, List<Student>> groupedStudents = students.stream() .collect(Collectors.groupingBy(student -> { if (student.getGrade() >= 90) { return "优秀"; } else if (student.getGrade() >= 80) { return "良好"; } else { return "及格"; } })); 上述代码中,我们定义了一个分类函数,根据学生的成绩来进行分组。通过stream的collect方法和groupingBy方法,我们可以得到一个Map对象,键为分组的条件("优秀"、"良好"和"及格"),值为对应条件的学生列表。 通过stream根据条件分组,我们可以更方便地对数据进行分类和处理,提供了更强大的功能和更简洁的代码。这是stream的一个重要特性,可以提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值