2016-08-17 5 views
0

На различных проектах, с которыми я работал, я нашел рисунок какУдобство класса для обработки карты <K, List<V>>

Map<Integer, List<String>> listMap = new HashMap<Integer, List<String>>(); 

public void addValue(Integer key, String value) { 
    if (!listMap.containsKey(key)) { 
     listMap.put(key, new ArrayList<String>()); 
    } 
    listMap.get(key).add(value); 
} 

для заполнения карты, которые имеют Lists как значения.

Поскольку это такой общий шаблон, я задавался вопросом, нет ли какого-либо класса convencience в стандартных библиотеках или что-то вроде guava, который управляет добавлением и удалением значений в эту структуру.

+0

Spring имеет 'MultiValueMap', но для этого нет стандарта. –

+1

Вы посмотрели документацию Guava? ['интерфейс Multimap'] (http://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html) – Jesper

+0

Также есть коллекции Apache Commons - [' интерфейс MultiMap '] (https://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/MultiMap.html) – Jesper

ответ

4

гуавы предлагает Multimap, который очень подходит для вашей цели:

ListMultimap<Integer, String> listMap = ArrayListMultimap.create(); 

public void addValue(Integer key, String value) { 
    listMap.put(key, value); 
} 

public List<String> getValues(Integer key) { 
    return listMap.get(key); 
} 

public Map<Integer, List<String>> asMap() { 
    // See documentation for details 
    return Multimaps.asMap(listMap); 
} 

Java 8 также предлагает более удобный способ получения и инициализации значения в одном операторе:

Map<Integer, List<String>> listMap = new HashMap<>(); 

public void addValue(Integer key, String value) { 
    listMap.computeIfAbsent(key, k -> new ArrayList<>()).add(value); 
} 

На в качестве побочного примечания я немного изменил бы ваш первоначальный пример, чтобы избежать дополнительного поиска, когда найден соответствующий ключ:

public void addValue(Integer key, String value) { 
    List<String> values = listMap.get(key); 
    if (values == null) { 
     listMap.put(key, values = new ArrayList<>()); 
    } 
    values.add(value); 
} 
+1

Возможно, стоит отметить, что 'Map >' может хранить значения, которые 'ListMultimap ' не может: первый может иметь пустой список, связанный с ключом, пока все еще сообщает, что ключ в 'keySet()'; последнее не может. Похоже, что это не повлияло бы на случай использования OP, но иногда это важная разница. –