2016-12-16 21 views
2

我想获得两个不同类型列表的交集和联合。我一直在尝试使用Java 8流,因为我认为这是最简单的方法。到目前为止,我每次都失败了。我简化了代码,使其可以轻松地复制。我有两个对象,数据1和数据2:Java 8 Stream交叉和自定义对象的两个不同列表的联合

例如:

public class Data2 { 

private int id; 
private String name; 
private String type; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getType() { 
    return type; 
} 

public void setType(String type) { 
    this.type = type; 
} 

public Data2(int id, String name, String type) { 

    this.id = id; 
    this.name = name; 
    this.type = type; 
    } 

} 




public class Data1 { 

private int id; 
private String name; 
private int amount; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public int getAmount() { 
    return amount; 
} 

public void setAmount(int amount) { 
    this.amount = amount; 
} 

public Data1(int id, String name, int amount) { 

    this.id = id; 
    this.name = name; 
    this.amount = amount; 
} 

} 



public class OutputData { 

private int id; 
private String name; 
private String type; 
private int amount; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public String getType() { 
    return type; 
} 

public void setType(String type) { 
    this.type = type; 
} 

public int getAmount() { 
    return amount; 
} 

public void setAmount(int amount) { 
    this.amount = amount; 
} 

public OutputData(int id, String name, String type, int amount) { 

    this.id = id; 
    this.name = name; 
    this.type = type; 
    this.amount = amount; 
} 

} 

它们有相似的领域。我需要根据ID(交叉)相交并把它们存储在一个输出(联盟?)类型为OutputData。

List<Data2> listOfData2 = new ArrayList<Data2>(); 

    listOfData2.add(new Data2(10501, "JOE" , "Type1")); 
    listOfData2.add(new Data2(10603, "SAL" , "Type5")); 
    listOfData2.add(new Data2(40514, "PETER", "Type4")); 
    listOfData2.add(new Data2(59562, "JIM" , "Type2")); 
    listOfData2.add(new Data2(29415, "BOB" , "Type1")); 
    listOfData2.add(new Data2(61812, "JOE" , "Type9")); 
    listOfData2.add(new Data2(98432, "JOE" , "Type7")); 
    listOfData2.add(new Data2(62556, "JEFF" , "Type1")); 
    listOfData2.add(new Data2(10599, "TOM" , "Type4")); 


List<Data1> listOfData1 = new ArrayList<Data1>(); 

    listOfData1.add(new Data1(10501, "JOE" ,3000000)); 
    listOfData1.add(new Data1(10603, "SAL" ,6225000)); 
    listOfData1.add(new Data1(40514, "PETER" ,2005000)); 
    listOfData1.add(new Data1(59562, "JIM" ,3000000)); 
    listOfData1.add(new Data1(29415, "BOB" ,3000000)); 

这是对我最好的尝试之一,没有任何错误的成功和大量的:

List<OutputData> od = listOfData1.stream().flatMap(x -> listOfData2.stream().filter(y -> x.getId().equals(y.getId())).map(y -> new OutputData(x.getId(), x.getName(), y.getType(), x.getAmount())).collect(Collectors.toList())); 

这应该返回ID号为10603的一个条目列表的主要类型的示例,名称SAL和所有其他填写的字段。

+0

您使用的是番石榴吗? – shmosel

+0

我不是,但我会对它开放 – gd000

回答

4

这应该这样做,但在本例中有5只记录在每个列表中有相同的ID。

List<OutputData> result = listOfData1.stream() 
     .flatMap(x -> listOfData2.stream() 
       .filter(y -> x.getId() == y.getId()) 
       .map(y -> new OutputData(y.getId(), x.getName(), y.getType(), x.getAmount()))) 
     .collect(Collectors.toList()); 
+0

我刚刚意识到我的测试用例是错误的。我要测试这个,并会让你知道 – gd000

+0

哇!谢谢! – gd000

+0

欢迎您。 :) –

0

我给你一些伪代码:

declare list 3 (type data3) 

for i = length of list 1 
    for j = length of list 2 
    if list1[i].getid == list2[j].getid 
     new data3 object with all relevant fields 
     add to list 3 
+0

感谢您的伪代码。我能够做到这一点没有问题与常规循环。我想用java 8流来做,虽然 – gd000

+0

没问题。我想知道为什么你使用比必要的更复杂的解决方案。干杯! – Eric