0

I am trying to filter out the duplicate Objects from a List of Objects. I am trying to remove the duplicate objects from the main List passed to the method and create another List containing those duplicate copies. This problem becomes complex as The Main Object in the List contains objects within it with which we need to check the duplicate. My requirement is somewhat as described below:

List<RateContract> "rateContractListWithOptions" contains two objects of RateContract:
[
    RateContract1 :{
      Rate :{tarifId: 1 //other variables will also be defined}
      Contract : {contractId:1}
    },
    RateContract2 :{
      Rate :{tarifId: 2}
      Contract : {contractId:1}
    }
]

Duplicate Rates will be checked using the equals method in the Rate class
At the end of the functions Processing 
"rateContractListWithOptions" this will have only one object of RateContract in list. maybe - [RateContract1 :{
      Rate :{tarifId: 1 //other variables will also be defined}
      Contract : {contractId:1}
    }]

and "duplicateRateContracts" this will contain the duplicate
[RateContract2 :{
      Rate :{tarifId: 2}
      Contract : {contractId:1}
    }]

I have written filterDuplicateRatesInSameContracts method, how do I enhance this?

    public class RateContract implements Serializable {

    private Rate rate = null;
    private Contract contract = null;
    private Map<Integer,List<Option>> optionMap = new HashMap<>();
    private Map<String, String> otherInformationMap = new HashMap<>();

    }

    public class Rate implements Serializable {

    private String promoCode = null;
    private String tiers_groupe_id = null;
    private String business_model = null;
    private Integer tarifId = null;
    private Integer ageMin = null;
    private Integer ageMinAbs = null;
    private String fuelType = null;

    @Override
    public boolean equals(Object o) {

        if (o == null || getClass() != o.getClass()) return false;
        Rate rate = (Rate) o;
        return Objects.equals(promoCode, rate.promoCode) &&
                Objects.equals(business_model, rate.business_model) &&
                !Objects.equals(tarifId, rate.tarifId) &&
                Objects.equals(ageMin, rate.ageMin) &&
                Objects.equals(ageMinAbs, rate.ageMinAbs) &&
                Objects.equals(fuelType, rate.fuelType) &&
                Objects.equals(ageMax, rate.ageMax) &&
                Objects.equals(ageMaxAbs, rate.ageMaxAbs);
    }

    @Override
    public int hashCode() {
        return Objects.hash(promoCode, business_model, tarifId, ageMin, ageMinAbs, fuelType, ageMax, ageMaxAbs);
    }
    }


    public class Contract implements Serializable {

    private Integer contractId; 
    ......
    }

    //The filtering Logic method is::

     private List<RateContract> filterDuplicateRatesInSameContracts(List<RateContract> rateContractListWithOptions) {
        Map<Integer, List<RateContract>> rateContractMap = new HashMap<>();
        rateContractListWithOptions.forEach(rateContract -> {
            rateContractMap.computeIfAbsent(rateContract.getContract().getContractId(), k -> new ArrayList<>()).add(rateContract);
        });
        List<RateContract> duplicateRateContracts = new ArrayList<>();
        rateContractMap.forEach((contract, rateContracts) -> {
            if (rateContracts.size() > 1) {
                for (RateContract rateContract : rateContracts) {
                    boolean isFound = false;
                    for (RateContract dupliRateContract : duplicateRateContracts) {
                        if (rateContract.getRate().equals(dupliRateContract.getRate())) {
                            isFound = true;
                            break;
                        }
                    }
                    if (!isFound) duplicateRateContracts.add(rateContract);
                }
            }
        });
        rateContractListWithOptions.removeAll(duplicateRateContracts);
        return duplicateRateContracts;
        }
Naman
  • 27,789
  • 26
  • 218
  • 353
  • 3
    Possible duplicate of [Remove duplicate from List java8](https://stackoverflow.com/questions/45418738/remove-duplicate-from-list-java8) – Butiri Dan May 16 '19 at 05:48
  • RateContract has inner object that will define its Duplicacy, The Solution you suggested is plain Object – Ishan Ghosh May 16 '19 at 06:01
  • I think you're probably creating some confusion by using the word 'duplicate'. That normally means items that are equal. In your case I think you want to remove any RateContract items that have a matching Rate earlier in the list. Correct? – sprinter May 16 '19 at 06:22
  • If you see I have Overridden the equals method in the Rate class.. So two rates are same or not will be defined by that equals method – Ishan Ghosh May 16 '19 at 06:24
  • I need some help implementing java 8 in filterDuplicateRatesInSameContracts method – Ishan Ghosh May 16 '19 at 06:25
  • Isn't your actual problems to remove `RateContract` from the `rateContractListWithOptions` if `rateContract.getRate()` is same as any other `RateContract` in the list? – Naman May 16 '19 at 06:51
  • Why is there a negation in `!Objects.equals(tarifId, rate.tarifId)`? – Thilo May 16 '19 at 06:52
  • @thilo.. tarifId can be different.. we are checking duplicates based on the other parameters – Ishan Ghosh May 16 '19 at 07:09
  • If it can be different, then you should exclude the condition altogether. Now they have to be different for the object to equal. Which means that `a.equals(a)` is always false. Which won't work very well. – Thilo May 16 '19 at 07:21
  • Thats not the case.. if the tarif id is not same but the remaining parameters are same it will return true – Ishan Ghosh May 16 '19 at 07:44
  • Yes, but if all parameters, including tarifId, are the same, then it will return false. Meaning no instance is equal to itself. – Thilo May 17 '19 at 08:03

1 Answers1

0

I'm interpreting your question as 'how do I move to a separate list all contracts in a list that have the same rate as an earlier item in the list'?

If so:

List<RateContract> duplicates = new ArrayList<>();
Set<Rate> rates = new HashSet<>();
Iterator<RateContract> iterator = contracts.iterator();
while (iterator.hasNext()) {
    RateContract contract = iterator.next();
    if (!rates.add(contract.getRate())) {
        iterator.remove();
        duplicates.add(contract);
    }
}

Note that this uses Iterator so that you can remove the contracts with matching rates as you move through the list. An alternative would be to collect them in the duplicates list and then remove them afterwards. Both would work.

sprinter
  • 27,148
  • 6
  • 47
  • 78