2015-07-26 24 views
6

Có một chút rắc rối khi sử dụng API luồng để tạo một ánh xạ một. Về cơ bản, nói rằng bạn đã có một lớp học.Bản đồ một-một với các luồng Java

public class Item { 
    private final String uuid; 

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

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

Tôi muốn một số Map<String, Item> để dễ dàng tra cứu. Nhưng với một số Stream<Item>, có vẻ như không có cách nào đơn giản để đến đó Map<String, Item>.

Rõ ràng, Map<String, List<Item>> không phải là không có điều:

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

Đó là trường hợp tổng quát hơn an toàn hơn, nhưng chúng tôi làm biết trong tình huống này là có sẽ chỉ là one-to-one. Tôi không thể tìm thấy bất cứ điều gì mà biên dịch mặc dù - Tôi đã đặc biệt đang cố gắng để muck với các thông số downstream để Collectors.groupingBy. Một cái gì đó như:

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

Tôi đang thiếu gì?

Trả lời

8

Sử dụng Collectors#toMap(Function, Function), tạo khóa từ mỗi's uuidItem làm giá trị chính nó.

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

Lưu ý từ các javadoc

Nếu các phím ánh xạ chứa bản sao (theo Object.equals(Object)), một IllegalStateException được ném khi hoạt động bộ sưu tập được thực hiện. Nếu các khóa được ánh xạ có thể có từ khóa trùng lặp, hãy sử dụng toMap(Function, Function, BinaryOperator) để thay thế.

+1

Nó đáng nói thêm rằng một ngoại lệ sẽ được ném ra nếu lặp đi lặp lại quan trọng xảy ra. –

1

groupingBy() thu thập các mục (số nhiều, dưới dạng List) bằng một khóa.

Bạn muốn toMap():

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

Có thể thử

itemStream.stream().collect(toMap(Item::getUuid,Functions.identity()); 
Các vấn đề liên quan