'Map Stream<> to an instance of @value class from Lombok tool
I encounter an interesting question from one interview: Building an aggregator which hold items and a sum of their prices converted to GBR currency.
A stream(java.util.stream.Stream) of Product objects is given, defined as:
@Value
class Product{
String name;
BigDecimal price;
String currency;
}
@value is from Lombok tool and can generate toString, equals and hashCode. It has getters for all the fields and single all arguments constructor).
The aggregator function map Stream to an instance of ItemsAggregate defined as follows:
@value
class ItemsAggregate{
List<Item> products;
BigDecimal total;
}
@Value
class Item{
String name;
BigDecimal price;
}
An interface Exchange is provided for converting 'price' to GBR use GBRExchange:
interface Exchange{
Optional<BigDecimal> rate(String currency);
}
The answer I can do for now is:
public class itemsAggregator implements Exchange{
private Exchange exchange;
itemsAggregator(GBRExchange GBRExchange){
this.exchange = GBRExchange;
}
ItemsAggregate aggregate(Stream<Product> products){
ItemsAggregate result = new ItemsAggregate();
result.products = products.stream().filter(0->o!=null).collect(products.getName() ->Collectors.toList());
result.total = products.stream().filter(o->o.getPrice()>=0).mapToInt(o -> o.getPrice()).sum();
result.total = exchange.rate(result.total);
return result;
}
@value
class ItemAggregate{
List<item> products;
BigDecimal total;
}
@value
class Item{
String name;
BigDecimal price;
}
}
The object is: 1. finish the aggregate function and get GBR 'total' variable. 2. Handling invalid values like null, empty and negative for GBRExchange as it could be buggy. 3. null, empty Stream and so on input to ItemsAggregate.aggregate() should return empty Stream instead of null before doing the mapping.
Could anyone give me some hints to fix this solution(as I'm unable to debug it), especially regarding point 2 and 3? And I'm not sure if I treat the @Value classes right.
Many thanks.
Solution 1:[1]
You might be looking for something like :
ItemsAggregate aggregate(List<Product> products) {
List<Item> items = products.stream()
.filter(Objects::nonNull)
.map(p -> new Item(p.getName(),p.getPrice()))
.collect(Collectors.toList());
BigDecimal total = products.stream()
.filter(o -> o.getPrice().compareTo(BigDecimal.ZERO) < 0)
.map(p -> exchange.rate(p.getCurrency()).orElse(BigDecimal.ZERO).multiply(p.getPrice()))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return new ItemsAggregate(items,total);
}
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 | Naman |
