Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle extra value in Java Streams?

I have the following 2 objects

Product       ProductInventory
-type         -Product
-price        -quantity  
              -country

I need to find cheapest by iterating through a list of ProductInventory. The steps are;

  1. if product.type == input_type and quantity > input_quantity
  2. totalPrice = product.price * input_quantity
  3. if country != input_country then totalPrice = totalPrice + input_tax
  4. sort records by the totalPrice from min to max
  5. get first record & map to a new object (country, quantity remaining, total price)

I cannot work out how to handle step 2, where I need to generate a total price, but how to create & use this field in a stream?

like image 461
user1298426 Avatar asked May 05 '26 10:05

user1298426


1 Answers

With a totalPrice field declared in ProductInventory, you can do the following;

private Optional<FinalEntity> doLogic(String inputCountry, String inputType, Integer inputQuantity, Integer inputTax) {
    return Stream.of(new Inventory(new Product("cola", 15), "germany", 1000))
            .filter(inv -> inv.getProduct().getType().equals(inputType) && inv.getQuantity() > inputQuantity)
            .peek(inv -> {
                Integer tax = inv.getCountry().equals(inputCountry) ? 0 : inputTax;
                inv.setTotalPrice((inv.getProduct().getPrice() * inputQuantity) + tax);
            })
            .sorted(Comparator.comparing(Inventory::getTotalPrice))
            .findFirst()
            .map(Util::mapToFinalEntity);
}

where

public class Product {

    String type;
    Integer price;

    // getters, setters, constructors
}

and

public class Inventory {

    Product product;
    String country;
    Integer quantity;
    Integer totalPrice;

    // getters, setters, and constructors
}

the result value is either an Optional.empty(), or you will have your resulting value in final entity format, I skipped last map to new object (country, quantity remaining, total price) which is a simple step at that point.

If you do not wish to have this field in Inventory, you can create a wrapper class on top of it, containing totalPrice, and map to it from inventories at the beginning of the stream.

like image 81
buræquete Avatar answered May 06 '26 23:05

buræquete