Ishan Arora
Ishan Arora

Reputation: 69

Check if multiple objects have same value of a field in java and remove duplicates based on other fields

So I have a list of objects. Suppose they have 2 fields startDate, endDate(data type is timestamp). So if startDate is equal to startDate of another object then I have to choose the object with higher endDate. How can I achieve this efficiently. I can use 2 for loops but that would have a high time complexity. Any better way of doing it? Thanks

Upvotes: 1

Views: 1311

Answers (3)

João Dias
João Dias

Reputation: 17500

You can use an HashMap for example and take advantage of the compute method:

hashMap.compute(newObject.getStartDate(), (key, value) -> 
   if (value == null) {
       newObject;
   } else if (value.getEndDate().after(newObject.getEndDate())) {
       value;
   } else {
       newObject;
   }
)

Upvotes: 1

Andy Brown
Andy Brown

Reputation: 12999

Here's an example that uses Integer instead of a date to make it easier to read but the principal is the same. Just change the comparison operators to suit and ensure your date class is usable as a map key.

Test class:

class Test {
  final Integer start;
  final Integer end;

  public Test(Integer s, Integer e) {
    this.start = s;
    this.end = e;
  }

  @Override
  public String toString() {
    return start + " " + end;
  }
}

Code example using a few instances of the Test class:

List<Test> l = Arrays.asList(new Test(1, 2), new Test(3, 4), new Test(1, 3), new Test(1, 1));

Map<Integer, Test> m = l.stream()
                        .collect(
                            Collectors.toMap(
                                o -> o.start,
                                Function.identity(),
                                (e, r) -> r.end > e.end ? r : e));

m.values().forEach(System.out::println);

Output:

1 3
3 4

Upvotes: 1

Eritrean
Eritrean

Reputation: 16498

Stream over your list, collect to map using your objects startdate as key and use a merging function to decide to which object to map if two or more objects have the same startdate by comparing the enddates. Something like:

Collection<YourObject> result =
            
yourList.stream()
        .collect(Collectors.toMap(YourObject::getStartDate,
                                  Function.identity(),
                                  (a, b) -> a.getEndDate().after(b.getEndDate()) ? a : b))
        .values();

Upvotes: 2

Related Questions