与 Java 流的一对一映射

One-to-one map with Java streams

使用 Stream API 获取一对一映射时遇到了一些麻烦。基本上,假设你有一个 class.

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()));
}

我错过了什么?

使用 Collectors#toMap(Function, Function),从每个 ItemuuidItem 生成密钥作为值本身。

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

来自 javadoc 的注释

If the mapped keys contains duplicates (according to Object.equals(Object)), an IllegalStateExceptionis thrown when the collection operation is performed. If the mapped keys may have duplicates, use toMap(Function, Function, BinaryOperator) instead.

groupingBy() 通过一个键收集项目(复数,作为 List)。

你想要toMap():

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

也许试试

itemStream.stream().collect(toMap(Item::getUuid,Functions.identity());