'Java Nested filter and Nested Streams
class Item {
int id;
List<PriceDetails> priceDetails;
String itemName;
}
class PriceDetails {
int price;
}
I am getting multiple items in a JSON file. I am trying to filter priceDetails with empty price (not the items, just removing all the priceDetails in the list with empty price)
I am able to write Java code and its working as expected, but I don't know how to write using Java Streams. Can someone help me?
Thanks in advance.
Java Code :
public static List<Item> filterByEmptyPrice(List<Item> items) {
List<Item> result= new ArrayList<>();
for(int i=0;i<items.size();i++) {
List<PriceDetails> temp= new ArrayList<>();
for(int j=0;j<items.get(i).PriceDetails.size();j++) {
if(nonNull(items.get(i).PriceDetails) && nonNull(items.get(i).priceDetails.get(j).priceDetails.price)) {
temp.add(items.get(i).priceDetails.get(j));
}
}
items.get(i).priceDetails= temp;
result.add(items.get(i));
}
return result;
}
Solution 1:[1]
Your filterByEmptyTicketPrice() method doesn't compile with the Item and PriceDetails model you gave.
The correct loop based implementation would be:
public static List<Item> filterByEmptyTicketPrice(List<Item> items) {
List<Item> result = new ArrayList<>();
for (Item item : items) {
List<PriceDetails> temp = new ArrayList<>();
for (PriceDetails priceDetails : item.priceDetails) {
if (nonNull(priceDetails.price)) {
temp.add(priceDetails);
}
}
// bug: you mutate your method input here
item.priceDetails = temp;
result.add(item);
}
return result;
}
Also, as noted above, you're mutating the input items. The correct way to do this with streams and without mutating the input would be:
public static List<Item> filterByEmptyTicketPrice(List<Item> items) {
return items.stream()
.map(item -> new Item(filterPrices(item.priceDetails)))
.collect(Collectors.toList());
}
static List<PriceDetails> filterPrices(List<PriceDetails> priceDetailsList) {
return priceDetailsList
.stream()
.filter(priceDetails -> priceDetails.price != null)
.collect(Collectors.toList());
}
This example assumes you've added a new Item constructor such as:
public Item(List<PriceDetails> priceDetails) {
this.priceDetails = priceDetails;
}
As others mentioned, you should update the model to use getters to access priceDetails and price making them private in your Item and PriceDetails classes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
