Comparing multiple fields of ArrayList using Lambda API and collecting the objects

New2Java :

I am facing a situation similar to described below in my project, of which I am unable to implement the code.

I have a POJO Class

    public class TranObject {

        public String loadId;
        public String vDate;
        public String dDate;
        public String pDate;

        public TranObject(String loadId, String vDate, String dDate, String pDate) {
            super();
            this.loadId = loadId;
            this.vDate = vDate;
            this.dDate = dDate;
            this.pDate = pDate;
        }
      //Getter and Setters
      //toString()

 }

Now I have another processor class where I want to implement some comparison between tranload objects that I am receiving through a data service call and collect them into another collection. The implementation logic is given in the comments below. Please read the below comments

import java.util.Arrays;
import java.util.List;

public class DemoClass {

    public static void main(String[] args) {
        List<TranObject> listObj = Arrays.asList(
                new TranObject("LOAD1", "20180102", "20180202", null),
                new TranObject("LOAD2", "20180402", "20180403", null),
                new TranObject("LOAD3", "20180102", "20180202", "20190302"),
                new TranObject("LOAD4", "20180402", "20180403", null),
                new TranObject("LOAD5", "20200202", "20200203", null)
        );

        /*
        IF (obj1, obj3 vdate and dDate are equal)
                IF(pDate == null for obj1 or obj3)
                    THEN obj1 and obj3 are equal/duplicates, and we collect them.
                ELSE IF(pDate != null for obj1 and obj3)
                    IF(pDate is same for obj1 and obj3)
                        THEN obj1 and obj3 are duplicates, and we collect them.
                    ELSE
                        THEN obj1 and obj3 are unique.
         */
    }
}

My End result should be a collection like List containing duplicate Tran objects for further update.

I searched internet in order to how to solve it using Lambda API. -> Tried using groupingBy first with vDate and then dDate, but then I could not compare them for pDate equality.

Can anyone help me solve this issue. A little help will be very helpful for me. I am stuck here

UPDATE: After some reading I am trying to implement the same by over-riding equals method in POJO class as shown below:

@Override
    public boolean equals(Object obj) {
        boolean isEqual=false;
        if(obj!=null) {
            TranObject tran = (TranObject) obj;
            isEqual=(this.vDate.equals(tran.getvDate()) && this.dDate.equals(tran.getdDate()));
            if(isEqual && this.pDate != null && tran.getpDate()!= null) {
                isEqual = (this.pDate.equals(tran.getpDate()));
            }
        }
        return isEqual;
    }

Still it's not working as expected... Can anyone please help me why??

Andrew Truett :

Sounds like TranObject needs an equals and hashCode method.

@Override
public boolean equals(Object obj) {
  //check instanceof and self comparison

  TranObject other = (TranObject) obj;


  if(this.vDate.equals(other.vDate) && this.dDate.equals(other.dDate)) {
    //if pDate is not given then consider them duplicate
    if(this.pDate == null || other.pDate == null)
      return true;

    //if pDate are the same then they are duplicate, otherwise they are unique
    return this.pDate.equals(other.pDate);
  }

return false;

}

//auto generated by Eclipse
@Override
public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((dDate == null) ? 0 : dDate.hashCode());
  result = prime * result + ((pDate == null) ? 0 : pDate.hashCode());
  result = prime * result + ((vDate == null) ? 0 : vDate.hashCode());
  return result;
}

Now that you have an equals method to determine if two TranObjects are considered equal (based on the rules you specified), just collect the elements that occur in the list more than once:

private static List<TranObject> findDuplicates(List<TranObject> list) {
  List<TranObject> result = new ArrayList<TranObject>();

  for(TranObject element : list) {
    if(Collections.frequency(list, element) > 1) 
      result.add(element);
  }

  return result;

}

This will return all elements that have a duplicate.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=26961&siteId=1