-2

I was working on my project, then I need the reach an element in the Json Data Look like:

[
  {
    "name": "Meltem",
    "items": [
      {
        "name": "Yilmaz",
        "histories": [
          {
            "date": 1615370705561,
            "school": "BAU"
          }
        ]
       }
     ]
   }
] 

So I can reach the element of name with:

var myData = data().
                stream().
                filter(x -> x.getName().equals("Meltem"))
                .collect(Collectors.toList())
                .get(0);

So, how to reach the school with using stream() in java 8?

Also, the getName() where I called;

@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "name",
        "items",
})
public class Package {
@JsonProperty("name")
    private String name;
@JsonProperty("items")
    private List<Item> items;
}
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724

3 Answers3

4

flatMap is your friend:

var mySchool = data().
    stream()
    .filter(x -> x.getName().equals("Meltem"))
    .flatMap(x->x.getItems().stream())
    .flatMap(item->item.getHistories().stream())
    .map(history->history.getSchool())
    .collect(Collectors.toList())
    .get(0);

flatMap() takes each element in the stream and maps each element to a Stream according to the operation you tell it to run. Then, it creates a Stream that containing all elements of each stream loaded previously.

The code I provided gets you a List with all schools in all histories in all items in all packages with the name MeItem.

If you just want to get the first element, I would use Stream#findFirst without converting it to a List:

var mySchool = data().
    stream()
    .filter(x -> x.getName().equals("Meltem"))
    .flatMap(x->x.getItems().stream())
    .flatMap(item->item.getHistories().stream())
    .map(history->history.getSchool())
    .findFirst()
    .orElse(null);//or use the Optional for whatever you want
dan1st
  • 12,568
  • 8
  • 34
  • 67
2

This should work:

var myData = data.stream()
                     .filter(x -> x.getName().equals("Meltem"))
                     .flatMap(x -> x.getItems().stream())
                     .filter(x -> x.getName().equals("Yilmaz"))
                     .flatMap(x -> x.getHistories().stream())
                     .map(History::getSchool)
                     .collect(Collectors.toList());

Assuming your classes look something like this:

public static class Package {
    private String name;
    private List<Item> items;

    public String getName() {
        return name;
    }

    public List<Item> getItems() {
        return items;
    }
}

public static class Item {
    private String name;
    private List<History> histories;

    public String getName() {
        return name;
    }

    public List<History> getHistories() {
        return histories;
    }
}

public static class History {
    private String school;

    public String getSchool() {
        return school;
    }
}
IntoVoid
  • 914
  • 4
  • 7
1
var myData = data().
            stream().
            filter(x -> x.getName().equals("Meltem"))
            .collect(Collectors.toList())
            .get(0).getHistories().get(0).getSchool();

Won't it work for you?

Sergiy Dakhniy
  • 538
  • 1
  • 4
  • 15