将增强型的for each循环转换为Java 8中的流。

huangapple go评论66阅读模式
英文:

Convert enhanced for each loop to streams java 8

问题

我正在尝试将使用增强型for-each循环编写的代码转换为Java中的流(Stream)。以下是传统代码和相应的流式代码:

传统代码部分:

List<OrderDetail> orderDetails = new ArrayList<>();
if (arInvoiceOrderResponseBody != null) {
    if (arInvoiceOrderResponseBody.getOrders() != null && 
        arInvoiceOrderResponseBody.getOrders().size() > 0) {
        for (OrderDetail orderDetail : arInvoiceOrderResponseBody.getOrders()) {
            if (orderDetail != null) {
                if (orderDetail.getStatusHistory() != null &&
                    orderDetail.getStatusHistory().size() > 0) {
                    for (StatusHistory statusHistory : orderDetail.getStatusHistory()) {
                        if (statusHistory != null) {
                            if (statusHistory.getStatusCode() != null) {
                                if (statusHistory.getStatusCode().equals("POD")) {
                                    orderDetail.setStatusDateTime(statusHistory.getStatus_date_time());
                                }
                            }
                        }
                    }
                }
            }
            orderDetails.add(orderDetail);
        }
        arInvoiceOrderResponseBody.setOrders(orderDetails);
    }
}

流式代码部分:

arInvoiceOrderResponseBody.getOrders().stream()
    .flatMap(order -> order.getStatusHistory().stream())
    .filter(statusHistory -> statusHistory.getStatusCode().equals("POD"))
    .forEach(statusHistory -> {
        // 在这里,如果条件为真,我需要执行以下操作:
        // 我需要将主订单对象的某个属性设置为状态历史对象的某个属性
        // order.setStatusDateTime(statusHistory.getStatus_date_time());
    });

请注意,流式代码中有一个forEach操作,您可以在其中执行所需的操作,即将主订单对象的属性设置为状态历史对象的属性。由于流是惰性执行的,只有在遇到终端操作时才会执行操作。

英文:

I am trying to convert code written in enhanced for each loop to streams in java.
Here is my traditional code

    List&lt;OrderDetail&gt; orderDetails = new ArrayList&lt;&gt;();
	if (arInvoiceOrderResponseBody != null) {
		if (arInvoiceOrderResponseBody.getOrders() != null &amp;&amp; 
         arInvoiceOrderResponseBody.getOrders().size() &gt; 0) {
         for (OrderDetail orderDetail : arInvoiceOrderResponseBody.getOrders()) {
				if (orderDetail != null) {
					if (orderDetail.getStatusHistory() != null &amp;&amp; 
                        orderDetail.getStatusHistory().size() &gt; 0) {
						for (StatusHistory statusHistory : orderDetail.getStatusHistory()) {
							if (statusHistory != null) {
								if (statusHistory.getStatusCode() != null) {
									if (statusHistory.getStatusCode().equals(&quot;POD&quot;)) {
										orderDetail.setStatusDateTime(statusHistory.getStatus_date_time());
									}
								}

							}
						}
					}
				}
				orderDetails.add(orderDetail);
			}
			arInvoiceOrderResponseBody.setOrders(orderDetails);
		}

Can anyone help me on replicating same functionality through streams.Any help would be greatly helpful

This is what i am trying

    arInvoiceOrderResponseBody.getOrders().stream() .flatMap(order -&gt;
    order.getStatusHistory().stream()) 
    .filter(statusHistory -&gt;statusHistory.getStatusCode().equals(&quot;POD&quot;))
    //Here if condition is true then i need to do this.I need to set one
    //of the property of main order object to one of the property of status 
    //history object 
    //order.setStatusDateTime(statusHistory.getStatus_date_time());

答案1

得分: 1

以下是我认为与Java 8最接近的内容:

arInvoiceOrderResponseBody.getOrders().forEach(
      orderDetail -> orderDetail.getStatusHistory().stream()
        .filter(statusHistory -> "POD".equals(statusHistory.getStatusCode()))
        .findFirst()
        .ifPresent(statusHistory -> orderDetail.setStatusDateTime(statusHistory.getStatus_date_time()))
    );

我注意到原始代码更改了现有的OrderDetail实例,然后将它们(全部)放入新集合中并替换原始集合。这看起来毫无意义!

英文:

Following is about as Java-8 as this is going to get in my opinion.

arInvoiceOrderResponseBody.getOrders().forEach(
      orderDetail -&gt; orderDetail.getStatusHistory().stream()
        .filter(statusHistory -&gt; &quot;POD&quot;.equals(statusHistory.getStatusCode()))
        .findFirst()
        .ifPresent(statusHistory -&gt; orderDetail.setStatusDateTime(statusHistory.getStatus_date_time()))
    );

I note the original code changes the existing OrderDetail instances but then puts them (all) into a new collection and replaces the original collection. This seems pointless on the face of it!

答案2

得分: 1

将其拆分为多个方法,并将其分解为两个流可能会起作用。类似这样:

public static ResponseBody processResponseBody(ResponseBody responseBody)
{
    if(validate(responseBody))
    {
        List<OrderDetail> orderDetails = responseBody.getOrders().stream()
            .filter(od -> validate(od))
            .map(od -> processOrderDetail(od))
            .collect(Collectors.toList());
        responseBody.setOrders(orderDetails);
    }
    
    return responseBody;
}

private static OrderDetail processOrderDetail(OrderDetail orderDetail)
{
    StatusHistory statusHistory = orderDetail.getStatusHistory().stream()
          .filter(sh -> validate(sh))
          .findFirst()
          .orElseThrow(() -> new IllegalArgumentException("No Status History Found"));
    orderDetail.setStatusDateTime(statusHistory.getStatus_date_time());

    return orderDetail;
}

private static boolean validate(ResponseBody responseBody)
{
    return responseBody != null && responseBody.getOrders() != null && responseBody.getOrders().size() > 0;
}

private static boolean validate(OrderDetail orderDetail)
{
    return orderDetail != null && orderDetail.getStatusHistory() != null && orderDetail.getStatusHistory().size() > 0;
}

private static boolean validate(StatusHistory statusHistory)
{
    return statusHistory != null && statusHistory.getStatusCode() != null && statusHistory.getStatusCode().equals("POD");
}

我将其拆分为处理OrderDetail对象的流和将StatusHistory减少为单个对象的流。我还将验证操作拆分成了单独的方法,以提高代码的简洁性和组织性。

英文:

Splitting it out into multiple methods and breaking it down into two streams may work. Something like:

  public static ResponseBody processResponseBody(ResponseBody responseBody)
{
if(validate(responseBody))
{
List&lt;OrderDetail&gt; orderDetails = responseBody.getOrders().stream()
.filter(od -&gt; validate(od))
.map(od -&gt; processOrderDetail(od))
.collect(Collectors.toList());
responseBody.setOrders(orderDetails);
}
return responseBody;
}
private static OrderDetail processOrderDetail(OrderDetail orderDetail)
{
StatusHistory statusHistory = orderDetail.getStatusHistory().stream()
.filter(sh -&gt; validate(sh))
.findFirst()
.orElseThrow(() -&gt; new IllegalArgumentException(&quot;No Status History Found&quot;));
orderDetail.setStatusDateTime(statusHistory.getStatus_date_time());
return orderDetail;
}
private static boolean validate(ResponseBody responseBody)
{
return responseBody != null &amp;&amp; responseBody.getOrders() != null &amp;&amp; responseBody.getOrders().size() &gt; 0;
}
private static boolean validate(OrderDetail orderDetail)
{
return orderDetail != null &amp;&amp; orderDetail.getStatusHistory() != null &amp;&amp; orderDetail.getStatusHistory().size() &gt; 0;
}
private static boolean validate(StatusHistory statusHistory)
{
return statusHistory != null &amp;&amp; statusHistory.getStatusCode() != null &amp;&amp; statusHistory.getStatusCode().equals(&quot;POD&quot;);
}

I broke it into a stream to process the OrderDetail object and a stream to reduce the StatusHistory to a single object. I also broke the validation into their own methods for brevity and organization.

huangapple
  • 本文由 发表于 2020年8月4日 03:17:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63235615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定