1

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

3
  • A HashMap with startDate as a key. Commented Sep 3, 2021 at 9:38
  • @user3159253 if possible can you give a code snippet. Thanks? Commented Sep 3, 2021 at 9:40
  • You could utilize the Comparable or Comparator interface. Your class could implement the Comparable interface and override the compareTo method. Commented Sep 3, 2021 at 10:18

3 Answers 3

3

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();
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.