2014-11-17 3 views
1

Когда я использую Maps.uniqueIndex с List, который содержит повторяющееся значение,гуавы Maps.uniqueIndex не допускает дубликатов

java.lang.IllegalArgumentException: duplicate key: 836 
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:115) 

отбрасывается.

Я нахожу это неудобным. Полагаю, что это имеет смысл, но если для корректной работы функции требуется уникальная коллекция, почему она принимает Iterable в качестве аргумента вместо Set?

List<GroupVO> groups = groupDao.getAll(groupIds); 

Map<String,GroupVO> groupMap groupMap = Maps.uniqueIndex(groups, new Function<GroupVO,String>() { 
    public String apply(GroupVO vo) { 
     return vo.getId().toString(); 
}}); 

ответ

7

Это просто не возможно иметь несколько значений для одного ключа в простом Map, таким образом uniqueIndex не может делать ничего другого.

Он принимает Iterable, потому что принятие только Set ограничило бы его возможные использования и все еще не решило проблему. Не значения в заданном Iterable должны быть уникальными, но результат применения данной функции для каждого из них.

Если вам нужно несколько значений на ключ, вы можете просто использовать Multimaps.index, что делает то же самое, но возвращает Multimap (который может содержать произвольное количество значений для каждой клавиши).

+1

Хотелось бы, чтобы была версия этой функции, которая бы просто перезаписывала вместо того, чтобы бросать исключение. Просто снова укусил с неожиданным состоянием. Кажется, что проверка, необходимая для того, чтобы убедиться, что эта функция не случайно потерпит неудачу, более чем исключает ее преимущества (в моем случае) – Marc

3

Я думаю, что то, что смущает людей здесь (включая меня, когда я не обращаю внимания), заключается в том, что типичные Карты (например, HashMap) будут спокойно принимать новое значение для ключа; новое значение заменяет старое, поэтому, если значения одинаковы, это тихий no-op. Семья неизменяемых * .Builder бросает при тех же обстоятельствах.

Смежные вопросы