I am attempting to create a Map<ProductKey, ProductDetail> for a list of Products that need to have their ProductDetail added to them. The ProductDetail object is read from a database from a service ProductDetailLookUpService. I have not added the service because it needs a lot of exposure to internal info. Products may or may not have the ProductDetail and similar Products may share the same ProductDetail. Here are the basic classes that make up the relationships.
@Data
static class ProductKey{
@EqualsAndHashCode.Include
private Long productCode;
@EqualsAndHashCode.Include
private Long productDetailCode;
}
@Data
class Product {
@EqualsAndHashCode.Include
private ProductKey productKey;
@EqualsAndHashCode.Include
private ProductDetail productDetail;
}
@Data
class ProductDetail{
@EqualsAndHashCode.Include
private Long productCode;
private String description;
private BigDecimal price;
private String category;
}
public static Optional<ProductKey> findProductKey(Long productCode,
List<ProductKey> productKeys){
return productKeys.stream().
filter(productKey -> productCode.equals(productKey.getProductCode()))
.takeWhile(productKey -> productKey != null).findFirst();
}
Here is my attempt to create the map of Map<ProductKey, ProductDetail>. I do not know how to deal with the potential null values when a Product does not have a ProductDetail. Also, the method productKey.getProductCode() does not seem to be recognized.
Here is my attempt:
public static void main(String[] args) {
//Service that uses database configuration to obtain ProductDetails based on
//ProductCodes
ProductDetailLookUpService service = ....
List<ProductKey> productKeyList = service.findProductKeys();
List<Long> productCodes = Arrays.toList(new Long []{23334L, 667777L,
55009L});
List<ProductDetail> productDetailList =
service.getProductDetailList(productCodes);
Map<Long, ProductDetail> productDetailMap =
mapProductCodeToProductDetail(productDetailList);
// At start Product does not have ProductDetails
// Products may share ProductDetails
// Products which do not yet have ProductDetails defined will return a null
// value in the productDetailMap
Map<ProductKey, ProductDetail> map =
productKeyList.stream().collect(toMap(productKey -> {
Optional<ProductKey> optKey =
findProductKey(productKey.getProductCode(),
productKeyList)
optKey.isEmpty()? null :
optKey.get(),
productDetailMap.get(productKey.getProductCode());
});
}
public static Optional<ProductKey> findProductKey(Long
productCode, List<ProductKey> productKeys){
return productKeys.stream().
filter(productKey ->
productCode.equals(productKey.getProductCode()))
.takeWhile(productKey -> productKey !=
null).findFirst();
}
I want to use Java 8 lambda to get the map to use to add the ProductDetail to Product. Here is what I want to use below, to produce a Map<ProductKey, ProductDetail>
Map<ProductKey, ProductDetail> hashMap = new HashMap<>();
productKeyList.stream().forEach( productKey -> {
Optional<ProductKey> optKey =
findProductKey(productKey.getProductCode(),
productKeyList);
if(optKey.isPresent()) {
hashMap.put(optKey.get(),
productDetailMap.get(optKey.get()));
}
});
Finally I want to use the map to add the ProductDetail to Product like this:
List<Product> products = service.readProducts();
products.stream().map( product -> {
product.setProductDetail(hashMap.get(product.getProductKey()));
return product;
}
).collect(toList());