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
-
A HashMap with startDate as a key.user3159253– user31592532021-09-03 09:38:32 +00:00Commented Sep 3, 2021 at 9:38
-
@user3159253 if possible can you give a code snippet. Thanks?Ishan Arora– Ishan Arora2021-09-03 09:40:18 +00:00Commented 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.addem– addem2021-09-03 10:18:04 +00:00Commented Sep 3, 2021 at 10:18
3 Answers
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();
Comments
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
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;
}
)