java 8中两个列表对象的交集

Myj*_*516 2 java arraylist intersect java-8 java-stream

java 8中的两个列表对象的交集.有人能告诉我我做错了什么吗?

List<Student> originalStudent = new ArrayList<>();
List<Student> newStudent = new ArrayList<>();

List<Student> intersectListStudent = new LinkedList<>()

originalStudent.add(new Student("William", "Tyndale",1));
originalStudent.add(new Student("Jonathan", "Edwards",2));
originalStudent.add(new Student("Martin", "Luther"),3);

newStudent.add(new Student("Jonathan", "Edwards",2));
newStudent.add(new Student("James", "Tyndale",4));
newStudent.add(new Student("Roger", "Moore",5));


originalStudent.forEach(n ->
        newStudent.stream()
                .filter(db -> !n.getName().equals(db.getName()) &&
                        !n.getLastName().equals(db.getLastName()))
                    .forEach(student-> intersectListStudent .add(student)));
Run Code Online (Sandbox Code Playgroud)

Nik*_*las 9

有人可以告诉我,我做错了什么?

你违反了的副作用原则,简而言之,在通过管道执行操作时,流不应该修改另一个集合.我没有测试过您的代码,但是,这不是您应该处理流的方式.


怎么做得更好?

只需使用List::contains过滤器的谓词来摆脱唯一值.

List<Student> students = originalStudent.stream()
                                        .filter(newStudent::contains)
                                        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

这个解决方案(理解方法List::contains)是基于使用实现的相等比较Object::equals.因此,需要在类中覆盖相同的方法Student.

编辑:请注意,自动覆盖Object::equals将铭记id相等计算.因此,相等性仅基于姓名和姓氏.(感谢@nullpointer).

没有Object::equals被覆盖?

您必须在filter使用另一个stream以及在谓词合格时Stream::anyMatch返回的方法中执行比较true.

List<Student> students = originalStudent.stream()
              .filter(os -> newStudent.stream()                    // filter
                  .anyMatch(ns ->                                  // compare both
                       os.getName().equals(ns.getName() &&         // name
                       os.getLastName().equals(ns.getLastName()))) // last name
              .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 加上一个用于'anyMatch`和`collect` :)的解决方案 (2认同)