0

I have ProductInfo object which looks like this

ProductInfo.java

    public class ProductInfo
    {
    private List<String> servicetagInfo;
    }

I have Order object like this which has list of Products info

OrderDetail.java

    public class OrderDetail
    {
    private String orderNum;
    private List<ProductInfo> productInfo;
    }
    

And then I have a Response object which basically has List of Order objects

Response.java

    public class Response
    {
    private List<OrderDetail> orderInfo;
    }  

I am getting response as expected.But right now in this format

    orderInfo:
    0: {orderNum: "162293591",...}
     productInfo:
     0: {servicetag_info: ["7LSMW33", "49SMW33"]}
     1: {servicetag_info: ["JF6XN33", "CQ5XN33"]}
     2: {servicetag_info: ["5VRR523", "13LR523"]}

Here I am trying to merge productInfo List to be like this

    productInfo:
    0: {servicetag_info: ["7LSMW33", "49SMW33","JF6XN33", "CQ5XN33","5VRR523", "13LR523"]}

Just add all strings into one main property.

Here is my code

    List<String> serviceTagList = new ArrayList<>();
    for (OrderDetail orderDetail : arInvoiceOrderResponseBody.getOrders()) {  //Here i am getting orders from external service
        if (orderDetail != null) {
            if (orderDetail.getProductInfo() != null && orderDetail.getProductInfo().size() > 0) {
                for (ProductInfo productInfoDetail : orderDetail.getProductInfo()) {
                    if (productInfoDetail != null) {
                        if (productInfoDetail.getServicetagInfo() != null) {
                            for (String serviceTag : productInfoDetail.getServicetagInfo()) {
                                serviceTagList.add(serviceTag);
                            }
                       }
                    }
                }
            }
        }
        ProductInfo productInfo = new ProductInfo();
        productInfo.setServicetagInfo(serviceTagList);
        orderDetail.setProductInfo(Arrays.asList(productInfo));
    }         

Can anyone suggest how can i achieve same using streams in java so that it will be readable.

1
  • If you could ensure those lists are not null by their nature or from the methods returning their values, you could simplify things to List<String> serviceTagList = orderDetails.stream() .filter(Objects::nonNull) .flatMap(od -> od.getProductInfo().stream()) .filter(Objects::nonNull) .flatMap(pi -> pi.getServicetagInfo().stream()) .collect(Collectors.toList()); Commented Jul 30, 2020 at 17:32

2 Answers 2

2

Try this:

Set<String> tags = order.stream()
            .flatMap(order -> order.getProductInfo().stream())
            .map(ProductInfo::getServicetagInfo)
            .collect(Collectors.toSet());

Full implementation:

for (OrderDetail orderDetail : arInvoiceOrderResponseBody.getOrders()) {
    if (orderDetail != null && orderDetail.getProductInfo() != null) {
        orderDetail.getProductInfo().removeAll(null); // Remove any null elems
        Set<String> tags = orderDetail.getProductInfo().stream()
            .flatMap(product -> (product.getServicetagInfo() == null) ? null : product.getServicetagInfo().stream())
            .collect(Collectors.toSet());
        tags.remove(null); // Remove null if exists
    }

    ProductInfo productInfo = new ProductInfo();
    productInfo.setServicetagInfo(tags);
    orderDetail.setProductInfo(Arrays.asList(productInfo));
}
Sign up to request clarification or add additional context in comments.

3 Comments

After getting Set of strings i am trying to set it to List<ProductInfo> object which is a property of OrderDetail object as you can see at the bottom of my code.Basically inside product info i am getting more than one object.But i need to add all strings into one object with property servicetagInfo and set List<ProductInfo> object to OrderDetail
Updated solution. FYI, this is not a platform for exact solutions. If you want to understand streams, please look at tutorials, then come back for any further questions.
If this works for you, please mark it as correct, and upvote. Thanks!
2

With streams your code could be like this:

arInvoiceOrderResponseBody.getOrders().stream()
            .filter(Objects::nonNull)
            .forEach(YourClassName::mergeProductInfo);

The method mergeProductInfo would be:

private static void mergeProductInfo(OrderDetail orderDetail) {

    List<String> serviceTagList = new ArrayList<>();

    if (orderDetail.getProductInfo() != null) {
        serviceTagList = orderDetail.getProductInfo().stream()
                .filter(Objects::nonNull)
                .map(ProductInfo::getServicetagInfo)
                .filter(Objects::nonNull)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }

    ProductInfo productInfo = new ProductInfo();
    productInfo.setServicetagInfo(serviceTagList);
    orderDetail.setProductInfo(Arrays.asList(productInfo));
}

It could be simplified if you could be sure that you are not going to receive null lists or elements.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.