簡體   English   中英

Java 8 Map KeySet Stream無法在Collector中使用

[英]Java 8 Map KeySet Stream not working as desired for use in Collector

我一直在努力學習Java 8的新功能接口功能,而且我在重構我之前編寫的代碼時遇到了一些困難。

作為測試用例的一部分,我想在Map結構中存儲一個讀取名稱列表,以便檢查這些讀取是否已在后續的代碼段中“修復”。 我正在轉換現有的Map>數據結構。 我將這個數據結構弄平的原因是因為在后續分析中不需要原始Map的外部“String”鍵(我在將它們合並到中間數據之前用它來隔離來自不同源的數據)。 這是我原來的程序邏輯:

public class MyClass {
  private Map<String, Map<String, Short>> anchorLookup;
  ...
  public void CheckMissingAnchors(...){
    Map<String, Boolean> anchorfound = new HashMap<>();

    // My old logic used the foreach syntax to populate the "anchorfound" map
    for(String rg : anchorLookup.keySet()){
      for(String clone : anchorLookup.get(rg).keySet()){
        anchorfound.put(clone, false);
      }
    }
    ...
    // Does work to identify the read name in the file. If found, the boolean in the map
    // is set to "true." Afterwards, the program prints the "true" and "false" counts in 
    // the map
   }
}

我試圖重構代碼以使用功能接口; 但是,我從我的IDE(運行Java 1.8.0_05的Netbeans 8.0 Patch 2)中收到錯誤:

public class MyClass {
  private Map<String, Map<String, Short>> anchorLookup;
  ...
  public void CheckMissingAnchors(...){

    Map<String, Boolean> anchorfound = anchorLookup.keySet()
      .stream()
      .map((s) -> anchorlookup.get(s).keySet())  // at this point I am expecting a 
      // Stream<Set<String>> which I thought could be "streamed" for the collector method
      // ; however, my IDE does not allow me to select the "stream()" method
      .sequential() // this still gives me a Stream<Set<String>>
      .collect(Collectors.toMap((s) -> s, (s) -> false);
      // I receive an error for the preceding method call, as Stream<Set<String>> cannot be 
      // converted to type String
    ...
   }
}

有沒有更好的方法使用Collection方法創建“anchorfound”映射,還是vanilla Java“foreach”結構是生成此數據結構的最佳方法?

我為代碼中的任何明顯錯誤道歉。 我的正式培訓不是計算機科學,但我想更多地了解Java的函數式編程概念的實現。

我相信你需要的是一個flatMap。

這樣,您可以將外部映射的每個鍵轉換為相應內部映射的鍵的流,然后將它們展平為單個String流。

public class MyClass {
  private Map<String, Map<String, Short>> anchorLookup;
  ...
  public void CheckMissingAnchors(...){

    Map<String, Boolean> anchorfound = anchorLookup.keySet()
      .stream()
      .flatMap(s -> anchorlookup.get(s).keySet().stream())
      .collect(Collectors.toMap((s) -> s, (s) -> false);
    ...
  }
}

EranflatMap 的建議很好,+1。

這可以通過使用Map.values()而不是Map.keySet()來簡化,因為map的鍵不用於任何其他目的,而不是用於檢索值。 流式傳輸Map.values()的結果給出了一個Stream<Map<String,Short>> 這里我們不關心內部映射的值,因此我們可以使用keySet()來提取鍵,從而提供Stream<Set<String>> 現在我們將這些集flatMapStream<String> 最后,我們像以前一樣將結果發送到收集器。

生成的代碼如下所示:

public class MyClass {
    private Map<String, Map<String, Short>> anchorLookup;

    public void checkMissingAnchors() {
        Map<String, Boolean> anchorfound = anchorLookup.values().stream()
            .map(Map::keySet)
            .flatMap(Set::stream)
            .collect(Collectors.toMap(s -> s, s -> false));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM