2016-12-22 2 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

Поскольку вся разница - это идентификатор, простой способ делает это для вас.

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 с ключами. Это все. Я добавил нулевое сравнение, если значение равно null. – 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', позволяющий пропускать только эти два значения, может избежать ненужной работы. Если мы предположим, что есть только два значения (или с помощью шага 'filter'), мы могли бы также использовать' partitioningBy' вместо 'groupingBy'. – Holger

+2

@ Хольгер Я полагал, что было бы полезно создать карту со всеми значениями исходной карты как ключей, но это будет зависеть от фактического использования - то есть, можем ли мы создать эту карту один раз и продолжать повторное использование ее для разных пар значений, или мы должны создавать его каждый раз, когда обновляется исходная карта. – 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)); 
Смежные вопросы