2015-03-02 40 views
4

說我有以下地圖:使用java 8流API轉換一個地圖到另一個地圖

Map<Member, List<Message>> messages = ... //constructed somehow 

我想使用java 8流API,以便獲得一個:

SortedMap<Message, Member> latestMessages = ... 

傳入SortedMap/TreeMap的比較器將基於消息sendDate字段。

此外,在發送的消息列表中,我將選擇將成爲排序映射關鍵字的最新消息。

我該如何做到這一點?

編輯1

Comparator<Message> bySendDate = Comparator.comparing(Message::getSendDate); 
SortedMap<Message, Member> latestMessages = third.entrySet().stream() 
     .collect(Collectors.toMap(e -> e.getValue().stream().max(bySendDate).get(), Map.Entry::getKey, (x, y) -> { 
      throw new AssertionError(); 
     },() -> new TreeMap(bySendDate.thenComparing(Comparator.comparing(Message::getId))))); 

我得到以下編譯錯誤:

The method collect(Collector<? super T,A,R>) in the type Stream<T> is not applicable for the arguments (Collector<Map.Entry<Member,List<Message>>,?,TreeMap>) 
+1

你確定你想要嗎?這意味着即使具有相同日期但發送者和接收者不同的消息存在,也只能有一個具有特定「sendDate」的'Message'。 – Holger 2015-03-02 16:41:54

+0

是的。基本上我會收到一封給特定會員的最新消息。 – balteo 2015-03-02 16:44:07

+0

我實際上正在實施一個消息框,比如what'sapp或環聊等等。 – balteo 2015-03-02 16:45:04

回答

9

讓我們解散分爲兩個部分這一點。

首先,變換Map<Member, List<Message>> messagesMap<Message, Member> latestMessages通過減少用於特定通信夥伴(Member)到最新的消息:

Map<Message, Member> latestMessages0 = messages.entrySet().stream() 
    .collect(Collectors.toMap(
     e -> e.getValue().stream().max(Comparator.comparing(Message::getSendDate)).get(), 
     Map.Entry::getKey)); 

在此,所得到的map未排序但每個映射將包含與該參與者分享的最新消息。


第二,如果你想擁有生成的地圖由sendDate排序,你必須添加其他輔助排序標準,以避免失去Messages碰巧有相同的日期。假定有一個Long的ID是唯一的,添加該ID作爲第二排序標準的消息具有相同的日期將是足夠的:

Comparator<Message> bySendDate=Comparator.comparing(Message::getSendDate); 
SortedMap<Message, Member> latestMessages = messages.entrySet().stream() 
    .collect(Collectors.toMap(
     e -> e.getValue().stream().max(bySendDate).get(), 
     Map.Entry::getKey, (x,y) -> {throw new AssertionError();}, 
     ()->new TreeMap<>(bySendDate.thenComparing(Comparator.comparing(Message::getId))))); 

由於由唯一ID排序應該解決任何多義性,我提供了一種合併函數將無條件拋出,因爲調用它永遠不應該被要求。

+0

非常感謝。但是我遇到了上述錯誤......我已經相應地編輯了我的帖子。 – balteo 2015-03-02 19:03:29

+2

你使用哪種編譯器?請注意,'新的TreeMap(...)'應該是'新的TreeMap <>(...)',我忘了這個''''東西,但是我的編譯器只產生一個警告(並且只有'-Xlint'),但也許你的編譯器是更挑剔... – Holger 2015-03-02 19:11:02

+0

謝謝。就是這樣。 – balteo 2015-03-02 19:29:02