Java8 how to get list of objects based on the value [closed]

Tags: , ,



Code is here order is having shipment and shipment having items and items having product

Order Class —————-

public class Order {

    private List<Shipment> shipment;

    public List<Shipment> getShipment() {
        return shipment;
    }

    public void setShipment(List<Shipment> shipment) {
        this.shipment = shipment;
    }
    
}

Shipment Class*

public class Shipment {
    
    private List<Item> item;
    
    public List<Item> getItem() {
        return item;
    }
    
    public void setItem(List<Item> item) {
        this.item = item;
    }
    
}

Item Class

public class Item {

    private Product product;

    public Product getProduct() {
        return product;
    }
    
    public void setProduct(Product product) {
        this.product = product;
    }
    
}

Product

 public class Product {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
    }

    List<Order> orderList = new ArrayList<Order>();
    List<Shipment> shipmentList = new ArrayList<Shipment>();
    List<Item> itemList = new ArrayList<Item>();
    
    Shipment shipment = new Shipment();
    shipment.setItem(itemList);
    shipmentList.add(shipment);
    
    Order order = new Order();
    order.setShipment(shipmentList);
    orderList.add(order);
    
    Item item1 = new Item();
    Item item2 = new Item();
    Item item3 = new Item();
    Item item4 = new Item();
    Item item5 = new Item();
    Item item6 = new Item();
    Item item7 = new Item();
    
    Product product = new Product();
    product.setName("Mobile");
    Product product1 = new Product();
    product1.setName("Mobile");
    Product product2 = new Product();
    product2.setName("Tv");
    Product product3 = new Product();
    product3.setName("AC");
    Product product4 = new Product();
    product4.setName("Tab");
    Product product5 = new Product();
    product5.setName("Bike");
    Product product6 = new Product();
    product6.setName("Bike");
    Product product7 = new Product();
    product7.setName("Bike");
    
    item1.setProduct(product);
    item1.setProduct(product1);
    item2.setProduct(product2);
    item3.setProduct(product3);
    item4.setProduct(product4);
    item5.setProduct(product5);
    item6.setProduct(product7);
    item7.setProduct(product7);
  
    itemList.add(item1);
    itemList.add(item2);
    itemList.add(item3);
    itemList.add(item4);
    itemList.add(item5);
    itemList.add(item6);
    itemList.add(item7);

Here want to pass product name like mobile in to a method that return list of order which matches product name mobile.. Could you please help how we can right using streams in java8

Answer

It could be better to use flatMap for the inner lists:

List<Order> filteredOrders = orderList
        .stream()
        .filter(o -> o.getShipment().stream()
            .flatMap(s -> s.getItem().stream()) // stream of Item
            .map(Item::getProduct) // stream of products
            .map(Product:getName)  // stream of product names
            .anyMatch("Mobile"::equals)
        )
        .collect(Collectors.toList());

Online demo

The chain of method map with method references may be replaced with a simple anyMatch:

List<Order> filteredOrders = orderList.stream()
        .filter(o -> o.getShipment().stream()
                .flatMap(s -> s.getItem().stream()) // stream of Item
                .anyMatch(i -> "Mobile".equals(i.getProduct().getName()))
        )
        .collect(Collectors.toList()); 

Update

If the filtered orders must contain only the shipments with filtered items, this implies that the entire chain of objects and their containers needs to be recreated:

new Order with new list of Shipment -> new Shipment with new list of Items -> new Item with a copy of Product from the matching product (with “Mobile” name).

Assuming that all the relevant constructors have been provided, the orders with the filtered products may look as follows:

List<Order> filteredOrderProducts = orderList
        .stream()
        .filter(o -> // same filter as before
                o.getShipment().stream()
                               .flatMap(s -> s.getItem().stream()) // stream of Item
                               .anyMatch(i -> "Mobile".equals(i.getProduct().getName()))
        )
        .map(o -> new Order(
                o.getShipment().stream()
                               .map(s -> new Shipment(
                                       s.getItem().stream()
                                                  .filter(i -> "Mobile".equals(i.getProduct().getName()))
                                                  .map(i -> new Item(i)) // copy constructor
                                                  .collect(Collectors.toList())
                               )) // new Shipment(List<Item> items)
                               .collect(Collectors.toList())
        )) // new Order(List<Shipment> shipments)
        .collect(Collectors.toList()); 
System.out.println("----norders with filtered products");
filteredOrderProducts.forEach(System.out::println);

Output

----
orders with filtered products
order: shipments=[items=[:product=product.name=Mobile]]
order: shipments=[items=[:product=product.name=Mobile]]

Updated online demo



Source: stackoverflow