2015-07-26 4 views
6

Имея небольшую проблему с использованием Stream API для получения сопоставления один к одному. В принципе, скажем, у вас есть класс.Индивидуальная карта с потоками Java

public class Item { 
    private final String uuid; 

    private Item(String uuid) { 
     this.uuid = uuid; 
    } 

    /** 
    * @return universally unique identifier 
    */ 
    public String getUuid() { 
     return uuid; 
    } 
} 

Я хотел бы получить Map<String, Item> для удобства поиска. Но, учитывая Stream<Item>, нет простого способа добраться до этого Map<String, Item>.

Очевидно, что Map<String, List<Item>> не не вещь:

public static Map<String, List<Item>> streamToOneToMany(Stream<Item> itemStream) { 
    return itemStream.collect(groupingBy(Item::getUuid)); 
} 

Это безопаснее и более общий случай, но мы сделать знаю в этой ситуации, что там будет только когда будет один-к-одному. Я не могу найти что-либо, что компилирует, хотя я специально пытался обмануть параметр downstream до Collectors.groupingBy. Что-то вроде:

// DOESN'T COMPILE 
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) { 
    return itemStream.collect(groupingBy(Item::getUuid, Function.identity())); 
} 

Что мне не хватает?

ответ

8

Используйте Collectors#toMap(Function, Function), генерируя ключ от каждого Itemuuid и Item в качестве самого значения.

public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) { 
    return itemStream.collect(Collectors.toMap(Item::getUuid, Function.identity())); 
} 

Примечание от Javadoc

Если отображенных ключей содержит дубликаты (в соответствии с Object.equals(Object)), IllegalStateException выбрасывается, когда выполняется операция коллекции. Если отображаемые ключи могут иметь дубликаты , вместо этого используйте toMap(Function, Function, BinaryOperator).

+1

Это стоит добавить, что будет сгенерировано исключение, если происходит повторение ключ. –

1

groupingBy() собирает предметы (множественное число, как List) ключом.

Вы хотите toMap():

public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) { 
    return itemStream.collect(toMap(Item::getUuid, Function.identity())); 
} 
-1

Может попробовать

itemStream.stream().collect(toMap(Item::getUuid,Functions.identity()); 
Смежные вопросы