使用java8流从另一个列表创建对象列表

使用java8流从另一个列表创建对象列表,java,java-8,java-stream,Java,Java 8,Java Stream,我有学生名单a和学生名单B 学生对象包含如下字段:否、年龄、城市、出生日期、薪水 我的列表A包含这些对象 A=[1 , 20 , Rome , 2001, 300 ] [2 , 21 , Dublin , 2005, 250 ] [3 , 24 , Istanbul, 2012, 350 ] [4 , 27 , Madrid , 2002, 450 ] [5 , 27 , London , 2005, 650 ] B=[1, 20 , Rome , 2014

我有学生名单a和学生名单B

学生对象包含如下字段:否、年龄、城市、出生日期、薪水

我的列表A包含这些对象

A=[1 , 20 , Rome ,    2001, 300 ]
  [2 , 21 , Dublin ,  2005, 250 ]
  [3 , 24 , Istanbul, 2012, 350 ]
  [4 , 27 , Madrid ,  2002, 450 ]
  [5 , 27 , London ,  2005, 650 ]
B=[1,  20 , Rome ,    2014, 700 ]
  [3,  24 , Istanbul, 2012, 350 ]
  [4,  27 , Madrid,   2009, 450 ]
我的列表B包含这些对象

A=[1 , 20 , Rome ,    2001, 300 ]
  [2 , 21 , Dublin ,  2005, 250 ]
  [3 , 24 , Istanbul, 2012, 350 ]
  [4 , 27 , Madrid ,  2002, 450 ]
  [5 , 27 , London ,  2005, 650 ]
B=[1,  20 , Rome ,    2014, 700 ]
  [3,  24 , Istanbul, 2012, 350 ]
  [4,  27 , Madrid,   2009, 450 ]
我想做的是提取ListA有但listB没有的学生对象,ListA和listB有(如否、年龄、城市),但薪水不同

 Result set = [5 , 27 ,London, 2005, 650 ]
              [2 , 21 ,Dublin ,2005, 250 ]
              [1,  20, Rome ,  2001, -400]
我想在java 8中使用流api。首先,我想将students对象提取到列表中,但我现在可以提取常见的student对象。我尝试使用noneMatch,但它不起作用。你有什么想法吗

List<Student> listDiffList = A.stream()
            // We select any elements such that in the stream of elements from the second list
            .filter(two -> B.stream()
            // there is an element that has the same name and school as this element,
                .anyMatch(one -> one.getNo().equals(two.getNo()) 
                        && one.getAge().equals(two.getAge())
                        && one.getCity().equals(two.getCity())))
            // and collect all matching elements from the first list into a new list.
            .collect(Collectors.toList());
List listDiffList=A.stream()
//我们从第二个列表中选择任何元素,以便在元素流中
.filter(两个->B.stream()
//有一个元素与此元素具有相同的名称和学校,
.anyMatch(one->one.getNo().equals(two.getNo())
&&1.getAge()等于(2.getAge())
&&1.getCity().equals(2.getCity())
//并将第一个列表中的所有匹配元素收集到新列表中。
.collect(Collectors.toList());

我使用了自定义收集器对象,看起来不是很好,但似乎可以工作:

List<Student> listDiffList =
  A.stream()
   .collect(ArrayList::new,
           (a, two) -> {
             Optional<Student> one = B.stream()
                                      .filter(s -> s.getNo().equals(two.getNo())
                                                   && s.getAge().equals(two.getAge())
                                                   && s.getCity().equals(two.getCity()))
                                      .findAny();


             if (one.isPresent()) {
                 if (!one.get().getSalary().equals(two.getSalary())) {
                     two.setSalary(two.getSalary()-one.get().getSalary());
                     a.add(two);
                 }
             }
             else a.add(two);
           },
           ArrayList::addAll);
列表列表difflist=
A.溪流()
.collect(数组列表::新建,
(一、二)->{
可选的一个=B.stream()
.filter(s->s.getNo().equals(两个.getNo())
&&s.getAge().equals(两个.getAge())
&&s.getCity().equals(两个.getCity())
.findAny();
if(一个.isPresent()){
如果(!one.get().getSalary().equals(two.getSalary())){
2.setSalary(2.getSalary()-1.get().getSalary());
a、 增加(2);
}
}
否则a.增加(两个);
},
ArrayList::addAll);

如果您有两个列表,其中您只需要一个从列表a减去列表B的结果列表,最明显的方法是使用
list
界面的
removeAll()
方法:

import java.util.List;
导入java.util.ArrayList;
公开课考试{
公共静态void main(字符串[]args){
List listA=List.of(整数值)(1),
整数值(2),
整数值(3),
整数值(4),
整数值(5));
List listB=List.of(整数值)(1),
整数值(3),
整数值(4));
列表结果=
新建ArrayList(listA);//创建相同的列表
listResult.removeAll(listB);//减去列表B中的元素
System.out.println(“listA:+listA”);
System.out.println(“listB:+listB”);
System.out.println(“listA\”减去“listB:+listResult”);
System.out.println();
}
}
将打印:

listA:[1,2,3,4,5]
清单B:[1,3,4]
listA“减”listB:[2,5]
您可以使用streams接口来完成,但它并没有那么简单。但是,
anyMatch()
noneMatch()
都可以在这里使用。它们都是返回布尔值的“短路终端操作”,因此它们是完美的谓词。只需对列表A进行流式处理,并使用带有谓词的筛选器来删除不需要的元素。对于
anyMatch()<代码>非匹配()
非常简单:

列表listResultStream=
listA.stream()
…然后使用以下任一方法:

.filter(intA->
!(listB.stream()
.anyMatch(intB->intB.equals(intA)))
…或:

.filter(intA->
listB.stream()
.noneMatch(intB->intB.equals(intA)))
并收集结果:

.collect(Collectors.toList());

对于您的特定场景,我可能不会选择streams解决方案。尽管如此,我后来还是添加了一些

我用过这个学生班。我决定注释掉
出生日期
,因为它与解决方案无关:

班级学生{
国际贸易编号;
智力年龄;
字符串城市;
//本地日期出生日期;
国际工资;
//学生(整数编号、整数年龄、字符串城市、整数出生日期、整数工资){
学生(整数编号、整数年龄、字符串城市、整数工资){
这个。否=否;
这个。年龄=年龄;
this.city=城市;
//this.birth_date=LocalDate.of(birth_date,1,1);//一月一日。
这个。薪水=薪水;
}
@凌驾
公共字符串toString(){
返回“(”+
否+“,”+
年龄+“,”+
城市+“,”+
//出生日期+“,”+
薪水+
")";
}
由于没有出生日期,我将这些记录用于两个列表:

List listStudentA=List.of(新生)(1,20,“罗马”,300),
新生(2,21,“都柏林”,250),
新生(3,24,“伊斯坦布尔”,350),
新生(4,27,“马德里”,450),
新生(5,27,“伦敦”,650),
新生(6,27,“巴黎”,650);
listStudentB=List.of(新生)(1,20,“罗马”,700),
新生(3,24,“伊斯坦布尔”,350),
新学生