0

I want to segregate duplicates and non duplicates from a list of objects based on property customerId and customerRegistration using java 8

segregate meaning

if I have 3 record with same customerId and customerRegistration, first record should add into nonduplicate list and 2 nd 3 record should be add in to duplicate list.

I have below pojo class created hashcode and equals method based on customerId and customerRegistration.

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);
}

}

I have written below logic in java7 which will work fine ,is there any way I can write using stream(convert forloop logic in the below code to stream)?

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
}

expecting output like below(from input assetList which is defined in the above execute1 function)

nonDuplicateList should have (asset1,asset3,asset6):

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);

duplicateList should have:(asset2,asset4,asset5)

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);
Gautham M
  • 4,816
  • 3
  • 15
  • 37
reddy
  • 79
  • 1
  • 11
  • Your example doesn't meet your discription, at least for the content of the `duplicateList` . I would expect the duplicate list to contain `asset1 & asset3` . – Eritrean Feb 09 '22 at 11:16
  • @basavaraddy Curious to know why the same `customerId` has multiple customer names associated to it? – Gautham M Feb 09 '22 at 11:27
  • @Eritrean edited my question nonDuplicateList should have asset1,asset3,asset6 and duplicateList should have asset2,asset4,asset5.As defined beginning of the question i want segregate the records for Example :if I have 3 record with same customerId and customerRegistration, first record should add into nonduplicate list and 2 nd 3 record should be add in to duplicate list. – reddy Feb 09 '22 at 11:32
  • @GauthamM its just an example i want identify the records which has occurred more than once based on customer and customer Registration field – reddy Feb 09 '22 at 11:34

2 Answers2

0

You can group the elements depending on adding to your set returns true or 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"));
}
Eritrean
  • 15,851
  • 3
  • 22
  • 28
0

You could use the same approach of using Set<Asset> set and collect it to a map using partitioningBy collector. Even though it would not cause much issue in the given example, Please read this answer to know why you shouldn't use a Collector to mutate an existing collection.

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

This would return a map with Boolean key, where true would be non-duplicates.

Gautham M
  • 4,816
  • 3
  • 15
  • 37