在java8中,根据多个属性上的属性从对象列表中分离重复和非重复



我想使用java 8 根据属性customerId和customerRegistration从对象列表中分离重复和非重复

分隔含义

如果我有3条具有相同customerId和customerRegistration的记录,第一条记录应该添加到非重复列表中,第二条和第三条记录应该被添加到重复列表中。

我在下面的pojo类中创建了基于customerId和customerRegistration的hashcode和equals方法。

public class Asset {
private String customerName;    
private int customerId;   
private String Type;   
private String customerRegistration;   
private int assetTagList;   
private String rso;    
private String active;   
private int billableUser;    
private int billableAsset;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
return customerId == asset.customerId && Objects.equals(customerRegistration, asset.customerRegistration);
}
@Override
public int hashCode() {
return Objects.hash(customerId, customerRegistration);
}

}

我已经在java7中编写了下面的逻辑,它会很好地工作,有没有任何方法可以使用流来编写(将下面代码中的forloop逻辑转换为流(?

public  Map<String ,List<Asset>> execute1() throws IOException {
List<Asset> assetList=new ArrayList<>();
Set<Asset> set=new HashSet<>();
List<Asset> duplicateList=new ArrayList<>();
List<Asset> nonDuplicateList=new ArrayList<>();
Map<String ,List<Asset>> map = new HashMap<>();
Asset asset1 = new Asset("French Customer1", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);
Asset asset2 = new Asset("French Customer2", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);

Asset asset3 = new Asset("French Customer3", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset4= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset5= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);

Asset asset6 = new Asset("French Customer5", 674, "Vehicle", "KNH 9008", 175, "FR", "Yes", 0, 0);

assetList.add(asset1); 
assetList.add(asset2);
assetList.add(asset3);
assetList.add(asset4);
assetList.add(asset5);
assetList.add(asset6);

for (Asset assetTemp:assetList){
if(set.add(assetTemp)){
nonDuplicateList.add(assetTemp);
}
else {
duplicateList.add(assetTemp);
}
}
map.put("duplicate",duplicateList);
map.put("nonDuplicateList",nonDuplicateList);


return map
}

预期输出如下(来自上面execute1函数中定义的输入资产列表(

nonDuplicateList应具有(资产1、资产3、资产6(:

Asset asset1 = new Asset("French Customer1", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);
Asset asset3 = new Asset("French Customer3", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset6 = new Asset("French Customer5", 674, "Vehicle", "KNH 9008", 175, "FR", "Yes", 0, 0);

重复列表应具有:(资产2、资产4、资产5(

Asset asset2 = new Asset("French Customer2", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);
Asset asset4= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset5= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);

您可以根据添加到您的集合来对元素进行分组,返回true或false:

public  static Map<String ,List<Asset>> execute2() throws IOException {
List<Asset> assetList=new ArrayList<>();
Asset asset1 = new Asset("French Customer1", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);
Asset asset2 = new Asset("French Customer2", 673, "Vehicle", "KNH 9009", 175, "FR", "Yes", 0, 0);
Asset asset3 = new Asset("French Customer3", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset4= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset5= new Asset("French Customer4", 673, "Vehicle", null, 175, "FR", "Yes", 0, 0);
Asset asset6 = new Asset("French Customer5", 674, "Vehicle", "KNH 9008", 175, "FR", "Yes", 0, 0);
assetList.add(asset1);
assetList.add(asset2);
assetList.add(asset3);
assetList.add(asset4);
assetList.add(asset5);
assetList.add(asset6);
Set<Asset> set=new HashSet<>();
return assetList.stream().collect(Collectors.groupingBy(x -> set.add(x) ? "nonDuplicateList" : "duplicate"));
}

您可以使用与使用Set<Asset> set相同的方法,并使用partitioningBy收集器将其收集到映射中。尽管在给定的示例中不会引起太多问题,但请阅读此答案,了解为什么不应该使用收集器来更改现有集合

assetList.stream().collect(Collectors.partitioningBy(set::add));

这将返回一个具有Boolean密钥的映射,其中true将是非重复的。

最新更新