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 java-stream :
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.