2015-04-28 18 views
11

Tôi mới sử dụng các biểu thức lambda và đang cố gắng sử dụng chúng để giảm mã sau đây thành tương đương lambda. Tôi đã nhìn vào giảm và flatMap và forEach, cũng như một số thứ khác, nhưng tôi rõ ràng là thiếu một cái gì đó bởi vì tất cả mọi thứ mà tôi cố gắng là một trong hai cú pháp không chính xác hoặc tôi không có một tài liệu tham khảo cho những gì tôi cần.Biểu thức Java Lambda cho các vòng lồng nhau có điều kiện

Tôi cần thực hiện phân tích từng yếu tố đối với tất cả các yếu tố khác trong bộ sưu tập. Tôi mã hóa rằng như vòng lặp lồng nhau với một điều kiện. Một khi các phần tử không phù hợp đã được xác định, việc tính toán được thực hiện bằng cả hai phần tử. Cuối cùng, tôi muốn có một tập hợp các kết quả cho mỗi phép tính so sánh.

Vì vậy, đây là mã gốc:

final List<Element> updated = new ArrayList<>(elements.size()); 

for (final Element first : elements) { 
    Attribute newAttribute = first.getAttribute(); 

    for (final Element second : elements) { 
     if (!first.equals(second)) { 
      newAttribute = newAttribute.add(computeChange(first, second)); 
     } 
    } 
    final Element newElement = new Element(first.getEntry(), newAttribute, first.getValue()); 
    updated.add(newElement); 
} 

Sau đó, tôi đã cố gắng rất nhiều biến thể của biểu thức lambda, đơn giản nhất trong số đó là:

elements.parallelStream() 
     .map(first -> new Element(first.getEntry(), first.getAttribute().add(
     computeChange(first, second)), first 
     .getValue())).collect(Collectors.toList())); 

Rõ ràng, điều này là sai vì không có tham chiếu đến thứ hai có sẵn cho tôi và không có điều kiện/bộ lọc cho lần thứ hai không bằng với đầu tiên.

Làm cách nào để giảm vòng lặp lồng nhau này với điều kiện trả về bộ sưu tập thành biểu thức lambda?

Mọi trợ giúp ở đây đều được đánh giá cao.

+3

Đây là khó khăn bởi vì bạn 'newAttribute = newAttribute.add (...) 'cập nhật không parallelizable. Điều này sẽ dễ dàng hơn nếu bạn có thể tổng hợp tất cả các kết quả 'computeChange' và sau đó tạo một' Attribute' (hoặc 'Element') từ tổng hợp đó. –

+0

Tôi sẽ để nó như vậy. –

+0

Trả về 'computeChange' là gì? Một 'Element',' Attribute', hoặc một số? –

Trả lời

3

Hãy thử:

elements.stream() 
    .map(first -> { 
     Attribute newAttribute = elements.stream().filter(second -> !first.equals(second)) 
       .map(second -> computeChange(first, second)) 
       .reduce(first.getAttribute(), (a, b) -> a.add(b)) 
       return new Element(first.getEntry(), newAttribute, first.getValue()); 
      }).collect(Collectors.toList())); 
+4

Tôi không nghĩ rằng '.foreach (newAttribute :: add);' sẽ hoạt động, vì 'add' dường như tạo thuộc tính mới. Tuy nhiên, có lẽ 'reduce' sẽ hoạt động. –

+0

@tobias_k foreach báo cáo lỗi: Phương thức foreach (Attribute :: add) không được xác định cho loại Stream . Sử dụng giảm giúp loại bỏ lỗi. – Todd

+0

pgerstoft, @tobias_k Tôi cần thay đổi đối số của foreach/reduce thành Thuộc tính: thêm nếu không tôi nhận được lỗi "Thuộc tính type không định nghĩa thêm (Thuộc tính, Thuộc tính) được áp dụng ở đây". Tuy nhiên, tôi không vượt qua các bài kiểm tra đơn vị, vì vậy tôi không nghĩ rằng việc cập nhật/thêm lặp lại đang hoạt động đúng cách. Tôi sẽ tiếp tục chọc vào nó, nhưng nếu bạn có bất cứ đề nghị nào, tôi rất thích nghe chúng. – Todd

Các vấn đề liên quan