简体   繁体   中英

How to get sum of doubles in list using stream?

Program is about purchases of companies. And i need to get some specific data from them using lambdas and streams.

COMPANY

@AllArgsConstructor
public class Company {
    private String name; // nazwa firmy
    private String cityHeadquarters; // siedziba firmy
    private int employees; // ilość pracowników
    private List<Purchase> purchaseList; // lista zakupów wykonanych przez firmę (co firma kupiła)


}

PRODUCT


@Data
@AllArgsConstructor
public class Product {
    private String name; // nazwa produktu
    private double price; // cena produktu

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Product)) return false;
        Product product = (Product) o;
        return Double.compare(product.price, price) == 0 &&
                Objects.equals(name, product.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, price);
    }
}

PURCHASE

@Data
@AllArgsConstructor
public class Purchase {             // klasa reprezentuje zakup
    private Product product;        // produkt zakupiony
    private LocalDate purchaseDate; // data dokonania zakupu
    private double quantity;        // zakupiona ilość produktu
    private UNIT unit;              // jednostka zakupu (np. w gramach)

}

MAIN unfortunately Main class is too big, but it consist mainly of created objects: products, companies and purchases. With list off all companies at the bottom.

How to return company that spent the most money on purchases? I tried with something like this:

 // 11. Zwróć firmę która dokonała zakupów na największą kwotę
    private static Company zad11(List<Company> companies) {
        List<Company> list1 = companies.stream()
        .map(c -> c+ c.getPurchaseList().stream()
        .filter(p -> p.getQuantity()*p.getProduct().getPrice()))
    }

You can use mapToDouble then terminate with sum() method. Something like this:

double sum = vals.stream().mapToDouble(Double::doubleValue).sum();

You can use the grouping feature of :

Map<Company, Double> map = companies.stream().collect(
    Collectors.groupingBy(                                 // To Map<Company, Double>
        Function.identity(),                               // Key: Company
        Collectors.summingDouble(c -> c.getPurchaseList()  // Value: Sum of all purchases
            .stream()
            .mapToDouble(p -> p.getProduct().getPrice())   // ... of all products and its prices
            .sum()                                         // ... as sum
        )   
    )
);

The key is each Company , the value of the map is the sum of prices of all its products within purchases - this assures Collectors::groupingBy(Function, Collector) .

The downstream collector Collectors::summingDouble(ToDoubleFunction) is responsible for summing all the prices.

If you need the company who spent the maximum amount, then you need to have max()

    Stream<Double> doubleStream = companies.stream().map(s -> s.getPurchaseList()).flatMap(k -> k.stream().map(j -> j.getProduct().getPrice()));
    List<Double> collect = doubleStream.mapToDouble(k -> k).boxed().collect(Collectors.toList());
    Optional<Double> max = collect.stream().max(Double::compareTo);
    System.out.println(max.get());

OUTPUT:

90000.0

GIST I created: https://gist.github.com/vishwaratna/47952c81976ade500231757662d8c5cc

Add new property in Company class as below

private double pruchseTotal;

companies.stream().forEach(c->c.setPruchseTotal( c.getPurchaseList().stream().collect(Collectors.summingDouble(p->p.getProduct().getPrice()*p.getQuantity())) ));
Company company = companies.stream().collect(Collectors.maxBy(Comparator.comparingDouble(Company::getPruchseTotal))).get();

You can use this for getting the list of Double values.

 List<Double> doubleList= values.stream().map(vals-> 
          vals.stream().mapToDouble(Double::doubleVal).sum()
          .collect(Collectors.toList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM