2017-11-09 9 views
3

私には、非アクティブとアクティブの両方のSalesOrdersのリストがあります。このリスト全体をループし、各SalesOrderがアクティブであった時間を設定したいと思います。以下のように(リストはすでにのStartTimeが発注される)特定の値を持つ次のアイテムが指定されたリストのアイテムの値を設定します。

私のループは次のとおりです。

for(int i = 0; i < salesOrders.size(); i++) { 
    if(salesOrders.get(i).getStatus() == RecordStatus.ACTIVE) { 
     ELDDutyLog activeSalesOrder = salesOrders.get(i); 

     for(int j = i + 1; j < salesOrders.size(); j++) { 
      if(salesOrders.get(j).getStatus() == RecordStatus.ACTIVE) { 
       ELDDutyLog nextActiveSalesOrder = salesOrders.get(j); 

       salesOrders.get(i).setActiveDurationMinutes(
        Minutes.minutesBetween(
         activeSalesOrder.getStartTime(), 
         nextActiveSalesOrder.getStartTime() 
        ).getMinutes() 
       ); 
       break; 
      } 
     } 
    } 
} 
return salesOrders; 

このアプローチは動作しますが、私は多分Javaの8を使用することにより、これを行うのより良い方法がなければならないと感じ?誰も私の周りの任意の方向を提供することはできますか?

+0

マイ悪いか

  • a.until(b, ChronoUnit.MINUTES)(すでにlongを返します)、それは@Eranがあると述べたのと同じようにタイプミス – user1501171

  • +0

    ました'RecordStatus'と' ELDRecordStatus'は同じですか?、2番目の 'if'文でなければ、それは決して実行されないので、不要です。 –

    +0

    'salesOrders.get(i)'と 'salesOrders.get(j)'は同じ 'SalesOrder'を表していることをどのように知っていますか?論理は明確ではありません。 – Eran

    答えて

    4

    無効な受注をスキップするたびに、リスト全体を再度ループする必要はありません。代わりに、アクティブな受注を一度フィルタリングして、次にアクティブな受注がフィルタリングされた一覧の次の注文であることを常に知ることができます。このような

    何か(テストしていません):

    List<ELDDutyLog> activeSalesOrders = salesOrders.stream() 
         .filter(so -> so.getStatus() == RecordStatus.ACTIVE) 
         .collect(Collectors.toList()); 
    
    for (int i = 0; i < activeSalesOrders.size() - 1; i++) { 
        activeSalesOrders.get(i).setActiveDurationMinutes(
            Minutes.minutesBetween(
             activeSalesOrders.get(i).getStartTime(), 
             activeSalesOrders.get(i+1).getStartTime() 
            ).getMinutes() 
           ); 
    } 
    
    +0

    私はこれが好きです。私は "一行"ですべてをやって大騒ぎを理解することはできません... +1 – Eugene

    +1

    @Eugene一般的に、私はあなたに同意します。この場合、リスト内の各項目を何回反復する必要があるのでしょうか。 OPの例では、各項目が何度も繰り返されます。この例では、各アイテムは1回反復され、アクティブなアイテムは2回反復されます。 Java 8ストリームでは、多くの場合、各項目を1回だけ反復することができます。これより大きなコレクションでは、パフォーマンスが向上する可能性があります。また、コードの意図をよりよく説明するために、流暢なAPIの表現力を好む人もいます。 –

    +0

    @MichaelPeyper私はこれを "一般的な"コメントとして意味していましたが、あなたのステートメントで私が同意できなかったものは何もありません – Eugene

    4

    私は私が正しく理解してほしいです。 (テストしていない)試してみてください。

    salesOrders.stream() 
        .filter(salesOrder -> salesOrder.getStatus() == RecordStatus.ACTIVE) 
        .reduce((current, next) -> { 
        current.setActiveDurationMinutes(
         Minutes.minutesBetween(
         current.getStartTime(), 
         next.getStartTime() 
        ).getMinutes() 
        ); 
        return next; 
        }); 
    

    正直に言うと...それはreduceのための奇妙な使用のビットですが、私はそれがうまくいくと思います。

    1

    2つのループをネストする必要はありません。 setActiveDurationMinutesコールの引数を計算するために検索したnextActiveSalesOrderは、外側ループの次の繰り返しで検索するactiveSalesOrderとなる同じオブジェクトです。それ以外にも、activeSalesOrderにその値が格納されているにもかかわらず、内部操作でsalesOrders.get(i)を不必要に呼び出しています。そのほかに

    ELDDutyLog activeSalesOrder = null; 
    for(ELDDutyLog nextActiveSalesOrder: salesOrders) { 
        if(nextActiveSalesOrder.getStatus() != RecordStatus.ACTIVE) continue; 
        if(activeSalesOrder != null) 
         activeSalesOrder.setActiveDurationMinutes(
          Minutes.minutesBetween(
           activeSalesOrder.getStartTime(), 
           nextActiveSalesOrder.getStartTime() 
          ).getMinutes() 
         ); 
        activeSalesOrder = nextActiveSalesOrder; 
    } 
    

    ... APIの種類Minutes.minutesBetween(a, b).getMinutes()ような何かを書くためにあなたが必要ですか! APIが何回多くの時間あなたにがほしいと言われる必要がありますか?
    java.timeと比較:

    1. ChronoUnit.MINUTES.between(a, b)は(DITO、まだ冗長性)
    関連する問題