Search code examples
javastreamhashmapnested-lists

Get minDate from nested array using java stream


I have List of MainData List<MainData>, I want to be able to get the minimum date with a filter where type is equals to "S" or "A". I think the best response type would be a HashMap<String(type), PojoClass> lowestDateOfTypeSandA

Lets say I have

List<MainData> mainDataList contains 3 elements:
pojo1 = mainDataList[0].getSubData().getPojoClass().size() is 2
pojo2 = mainDataList[1].getSubData().getPojoClass().size() is 3
pojo3 = mainDataList[2].getSubData().getPojoClass().size() is 1

ex:

  • the lowest "S" is in mainDataList[1].getSubData().getPojoClass().get(2)
  • the lowest "A" is in mainDataList[2].getSubData().getPojoClass().get(0)

Structure:

MainData.java
 - SubData getSubData()

SubData.java
 - List<PojoClass> getPojoList()

PojoClass.java
 - XMLGregorianCalendar getdate();
 - String getType();

Convert XMLCalender to Java Date

   public static Date convertXMLGregorianCalendarToDate(XMLGregorianCalendar xmlGregorianCalendar) {
        return xmlGregorianCalendar.toGregorianCalendar().getTime();
    }

I have tried a couple of things but I need to be able to dtream from Maindata so I get all the other elements as well.

Collection<PojoClass> pojoWithMinDate = pojoClassList.stream().collect(Collectors.toMap(
        PojoClass::getType,
        Function.identity(),
        (p1, p2) -> p1.getDate() > p2.getDate() ? p1 : p2))
    .values();

   List<PojoClass> result = pojoClassList.stream()
                .filter(p -> "S".equals(p.getType() || "A".equals(p.getType())
                .collect(Collectors.toList());

Solution

  • Not tested.

    Comparator<XMLGregorianCalendar> xgcComp
            = Comparator.comparing(xgc -> xgc.toGregorianCalendar().getTime());
    Map<String, Optional<PojoClass>> lowestDateOfTypeSAndA = mainDataList.stream()
            .flatMap(md -> md.getSubData().getPojoClass().stream())
            .filter(p -> p.getType().equals("S") || p.getType().equals("A"))
            .collect(Collectors.groupingBy(PojoClass::getType,
                    Collectors.minBy(Comparator.comparing(PojoClass::getdate, xgcComp))));
    

    The flatMap operation turns our strem of MainData into a stream of PojoClass.

    The groupingBy operation uses a so.called downstream collector to further process each group. In this case into the minimum POJO by date from that group. Since there may be no elements and hence no minimum, an Optional is collected into.