Search code examples
javajava-streamcollectors

Converting a List<MyObject> into a Map<Integer, String> based on the Max MyObject property in Java 8


I have a List<MyObject>. It contains multiple records for one objectId.

MyObject class looks like

class MyObject{
  int id;
  int objectId;
  String status;
  LocalDate updatedTimestamp;
}

I need a Map<Integer, String> with objectId as Key and corresponding status as a Value.

I need to consider only the record for one objectId with latest updatedTimestamp.

Different timestamps will have different status. Need only the latest one.

I didn't find a way of achieving this. I know I can get Map<integer, Optional<MyObject>> by applying groupingBy() and maxBy().

Please advise.


Solution

  • It can be done using collector groupingBy() in conjunction with collectingAndThen() and maxBy().

    Collector maxBy() expect a comparator as an argument and produces an optional result. To create a comparator, we can make use of the Java 8 method Comparator.comparing().

    List<MyObject> objects = // initializing the source list.
            
    Map<Integer, String> statusByObjectId = objects.stream()
        .collect(Collectors.groupingBy(
            MyObject::getObjectId,
            Collectors.collectingAndThen(
                Collectors.maxBy(Comparator.comparing(MyObject::getUpdatedTimestamp)),
                (Optional<MyObject> result) -> result.orElseThrow().getStatus())
            ));