2016-12-22 77 views
2

我已經實現使用Java 8.重構的Java 8流代碼

Map<String, String> coMap = getHashMap(); 

String newCoName = coMap.entrySet() 
        .stream() 
        .filter(coEntry -> coEntry.getValue().equals(newcoId)) 
        .map(coEntry -> coEntry.getKey()) 
        .collect(Collectors.joining()); 


String oldCoName = coMap.entrySet() 
        .stream() 
        .filter(coEntry -> coEntry.getValue().equals(oldcoId)) 
        .map(coEntry -> coEntry.getKey()) 
        .collect(Collectors.joining()); 

現在下面的代碼。我想知道更好的方法,而不是重複兩次相同的代碼行。

+0

等的方法?或for循環? – khelwood

+0

將代碼放入傳遞coId作爲參數的方法中:'getCoName(String coId)' – Pau

回答

5

由於整個差異是一個id,所以一個簡單的方法可以幫助你。

String getName(int id) { // supposed id is an integer 
    return coMap.entrySet() 
      .stream() 
      .filter(coEntry -> coEntry.getValue().equals(id)) 
      .map(coEntry -> coEntry.getKey()) 
      .collect(Collectors.joining()); 
} 
0

你可以使用這個輔助方法:

public static String join(Map<String, String> map, String value) { 
    return map.keySet().stream() 
      .filter(key -> Objects.equals(map.get(key), value)) 
      .collect(Collectors.joining()); 
} 

這裏使用該方法的一些示例代碼:

Map<String, String> coMap = new HashMap<>(); 
    coMap.put("A", null); 
    coMap.put("B", "V"); 
    coMap.put("C", "V"); 
    coMap.put("D", "Z"); 
    coMap.put("E", "Z"); 
    coMap.put("F", null); 

    System.out.println("Vs: " + join(coMap, "V")); 
    System.out.println("Zs: " + join(coMap, "Z")); 

這裏輸出:

Vs: BC 
Zs: DE 
+0

是否有刪除'.map(coEntry - > coEntry.getKey())'的原因? – Tom

+0

你在鍵盤右鍵?因此這個算法可以避免將Map.Entrys映射到鍵。就這樣。如果值爲空,我添加了空值安全比較。 – Harmlezz

+0

*「你在鍵盤右鍵?」*不,我不是。 – Tom

10

不是重複相同的代碼兩次兩次執行相同的代碼一個更大的問題。

這將是更有效地運行單個Stream管道產生的輸出:

Map<String,String> keysByValue = 
      coMap.entrySet() 
       .stream() 
       .collect(Collectors.groupingBy(Map.Entry::getValue, 
               Collectors.mapping(Map.Entry::getKey, 
                    Collectors.joining()))); 

這將使你的原來的Map(不僅是兩個值的原代碼,每個值搜索),聯合鍵具有該值。

然後你可以從Map提取所需的數據:

String newCoName = keysByValue.get(newcoId); 
String oldCoName = keysByValue.get(oldcoId); 

樣品的輸入和輸出:

Map<String,String> coMap = new HashMap<>(); 
coMap.put("a","foo"); 
coMap.put("b","foo"); 
coMap.put("c","bar"); 
coMap.put("d","bar"); 
Map<String,String> keysByValue = ... // same as the code above 
String newValueKeys = keysByValue.get("foo"); 
String oldValueKeys = keysByValue.get("bar"); 
System.out.println (newValueKeys); 
System.out.println (oldValueKeys); 

輸出:

ab 
cd 
+3

除'newcoId'和'oldcoId'之外,是否還有其他值還不清楚。如果是這樣,只讓這兩個值通過的「過濾」步驟可以避免做不必要的工作。如果我們假設只有兩個值(或者使用'filter'步驟),我們也可以使用'partitioningBy'而不是'groupingBy'。 – Holger

+2

@Holger我認爲用原始Map的所有值作爲關鍵字來生成一個Map是有用的,但這取決於實際的用法 - 也就是說,我們是否可以生成一次該地圖並繼續將其用於不同的對的值,或者我們必須在每次更新原始地圖時生成它。 – Eran

0

其它方式使用帶有FunctionalInterface Predicate ,你的條件過濾器將是動態的

public static Predicate<Map.Entry> getPredicate(String col) { 
    return p -> p.getValue().equals(col); 
} 

public static String getName(HashMap<String, String> coMap, Predicate<Map.Entry> predicate) { 
    return coMap.entrySet() 
      .stream() 
      .filter(predicate) 
      .map(coEntry -> coEntry.getKey()) 
      .collect(Collectors.joining()); 
} 

在調用代碼:

getName(coMap, getPredicate(newcoId)); 
    getName(coMap, getPredicate(oldcoId));