0

I have List<Item> that contains List<SubItem> objects inside and I need to return first date of SubItem. I'd like to use streams for this. I know that SubItem is never null or empty.

Logic behind is to retrieve date from SubItem which for all Item objects are the same. Loop through Item list then loop through SubItem (each Item has list of SubItem) and from the first SubItem return date.

Using non stream:

public LocalDate getSubItemDate(List<Item> items) {
    LocalDate date = null;
    for (Item item : items) {
        List<SubItem> subItems = item.getSubItems().getSubItem();
        for (SubItem si: subItems) {
            XMLGregorianCalendar rawDate = si.getSubItemDate().getVal();
            return rawDate.toGregorianCalendar().toZonedDateTime().toLocalDate();
        }
    }
    return date;
}

And using stream I've tried so far and I want to have something like this:

// but it's boolean...
public LocalDate getSubItemDate(List<Item> items) {
    return items
        .stream()
        .anyMatch(item -> 
                item.getSubItems().getSubItem()
                .stream()
                .anyMatch(si-> 
                    si.getSubItemDate().getVal().toGregorianCalendar().toZonedDateTime().toLocalDate()));
Naman
  • 27,789
  • 26
  • 218
  • 353
Poli
  • 77
  • 1
  • 11

1 Answers1

1

As per your first code snippet, there is no need to write a for loop. You can directly get the first item out of the list after checking the list size.

if (items.size() > 0) {
    Item item = items.get(0);
    List<SubItem> subItems = item.getSubItems().getSubItem();
    if (subItems.size() > 0) {
        XMLGregorianCalendar rawDate = subItems.get(0).getSubItemDate().getVal();
        return rawDate.toGregorianCalendar().toZonedDateTime().toLocalDate();
    }
}
return null;

Using streams,

items.stream()
    .findFirst()
    .flatMap(item -> item.getSubItems().getSubItem().stream().findFirst()
               .map(si -> si.getSubItemDate().getVal().toGregorianCalendar().toZonedDateTime().toLocalDate()))
.orElse(null); //or use orElseThrow to throw an exception

Also, using getSubItems().getSubItem() sounds odd, it should have been just getSubItems().

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
  • Is there a way to not result in ```null``` using stream? – Poli Jan 25 '21 at 11:15
  • 1
    As per your code, you were returning a null. That is why I added it. If you are sure the list won't be empty, you can add `orElseThrow` to throw an exception. – Thiyagu Jan 25 '21 at 11:22