2017-08-09 52 views
3

我正在嘗試將我們的傳統循環轉換爲流的框架。我的問題是我寫了兩個獨立的邏輯來獲得價格和顏色,但我想合併這兩個在一起,這將是像樣形成地圖問題的Java流

代碼來獲取價值

List<Double> productPrices = product.getUpcs() 
      .stream() 
      .map(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue()) 
      .distinct() 
      .sorted(Comparator.reverseOrder()) 
      .collect(Collectors.toList()); 

代碼來獲得下價格的顏色

 product.getUpcs() 
      .stream() 
      .filter(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue() == 74.5) 
      .flatMap(e -> e.getUpcDetails().getAttributes().stream()) 
      .filter(e2 -> e2.getName().contentEquals("COLOR")) 
      .forEach(e3 -> System.out.println(e3.getValues().get(0).get("value"))); 

我harcoded價格在上面的部分,以獲得顏色,相反,我想獲得,作爲從價格值列表輸入和在

01得到的輸出

我試圖合併這兩個都沒有成功,任何幫助將appriciated。

+1

看起來像某種'groupingBy',你需要......因爲你需要一個'Map'作爲結果 – Eugene

+2

作爲一個附註,*從不*使用'double'來表示貨幣價值。你會在網上找到大量關於它的文章...... – Holger

回答

1

我建議你檢查一下this or similar tutorial以瞭解它是如何工作的。

解決方案的關鍵是瞭解Collectors.groupingBy()的功能。作爲一個方面說明,它還顯示了一種更好的方式來處理Java中的定價信息。

但你需要做的是這樣的:

Map<Double, Set<String>> productPrices = product 
      .stream() 
      .map(e -> e.getUpcDetails()) 
      .collect(
        Collectors.groupingBy(Details::getPrice, 
        Collectors.mapping(Details::getColors, Collectors.collectingAndThen(
          Collectors.toList(), 
          (set) -> set 
            .stream() 
            .flatMap(Collection::stream) 
            .collect(Collectors.toSet()))) 

      )); 

因爲你的問題是有點不清楚的參與類的細節,我認爲這種簡單的類結構:

class Details { 
    private double price; 
    private List<String> colors; 

    double getPrice() { return price; } 
    List<String> getColors() { return colors; } 
} 

class Product { 
    private Details details; 

    Details getUpcDetails() { return details; } 
} 

```

可以優化上面的代碼,但我特別留下了在映射收集器中過濾和映射顏色的可能性。

1

您可以先打開你的第二個流成獲得的產品(設爲過濾/按價格分類)一List並把它轉換到顏色的List的方法:

List<Color> productsToColors(final List<Product> products) { 
    return products.stream() 
     .flatMap(e -> e.getUpcDetails().getAttributes().stream()) 
     .filter(e2 -> e2.getName().contentEquals("COLOR")) 
     .map(e3 -> e3.getValues().get(0).get("value")) 
     .collect(toList()); 
} 

可以使用groupingBy收藏家收集所有產品通過他們的價格在List,然後用第二個創建第二個流和productsToColors方法得到你想要的地圖:

Map<Double, List<Color>> colors = product.getUpcs().stream() 
    .collect(groupingBy(e -> e.getUpcDetails().getPrice().getRetail().getPriceValue()) 
    .entrySet().stream() 
    .collect(toMap(Entry::getKey, e -> productsToColors(e.getValue()))); 

您也可以使用groupingBy創建TreeMap,以便顏色貼圖按價格排序。

作爲一個側面提示要小心比較這樣的平等雙值。你可能想先把它們四捨五入。或使用長變量乘以100(即美分)。