2016-12-16 49 views
1

我想弄清楚處理以下情況的最佳方法。如何流化對象的映射並將拼合圖映射到新對象的單個列表?

我有地圖事件,在通過時間戳分組的數據庫發生了:

[2016-04-01 00:00:00, [event1, event2, event 3]] 
[2016-02-01 00:00:00, [event5, event6]] 
[2016-01-01 00:00:00, [event7, event8, event9, event10]] 

我想在一個tableview中呈現這些數據與每個事件的時間戳一行。但是,有些值可能會重複。

例如:

事件的定義是

class Event() {  
    LocalDateTime timestamp 
    String eventName 
    String eventDescription 
} 

我想拉平到這樣

class DisplayEvent() {  
    LocalDateTime timestamp 
    Collection<String> eventName 
    Collection<String> eventDescription 
} 

這樣的結構原始地圖我留下了轉換後以下列表:

displayEvent1 
displayEvent2 
displayEvent3 

其中每個顯示事件都有來自原始事件的密鑰,但包含所有可變數據的數組。

我創建的地圖如下:

Map<LocalDateTime, List<Event>> eventsByTimestamp = 
        events 
        .stream() 
        .collect(Collectors.groupingBy(ev -> ev.timestampProperty().get())); 

希望是有道理的。

+0

也許減少比壓扁一個更好的詞,有些想法彈出然後:-) –

回答

1

在我眼中,最好的方法取決於你的任務的細節。

一個更通用的方法是一類Event

public class Event 
{ 
    LocalDateTime timestamp; 
    String eventName; 
    String eventDescription; 
} 

然後你可以優雅地通過時間戳創建分組:

event. 
    stream(). 
    collect(groupingBy(Event::getTimeStamp)); 

這當然不是那麼有效,將工作的很好更少的事件。所以,你可以考慮從數據庫中提取的分組期間發生的事件,例如:

public class EventRepository 
{ 
    Map<LocalDateTime, List<Event>> getAllEventsGroupedByTime(); 
} 

getAllEventsGroupedByTime您將實例的事件對象,並把它們相應的組中,而不在另一個應用程序層重複這個計算。

的另一種方法是這樣的:

public class Event 
{ 
    String eventName; 
    String eventDescription; 
} 

public class EventGroup 
{ 
    LocalDateTime timestamp; 
    List<Event> events; 
} 

public class EventGroupRepository 
{ 
    List<EventGroups> getEventGroups(); 
} 

老實說,我看到了第二個解決方案小的好處(例如,一些對象裁判都不能倖免)。所以我會選擇1號,並且在提取數據庫的時候把它們分組,尤其是如果事件數量不是很大。這似乎更加性感,因爲事件時間自然屬於事件。

更新:

好吧看來你想使用酷的Java 8流:-)然後,您可以考慮添加以下簡單的方法,所有的事件轉換成顯示事件的集合DisplayEvent(或者創造某種輔助類的):

public static DisplayEvent combine(DisplayEvent evt1, DisplayEvent evt2) 
{ 
    if (evt1.getActivityTimestamp() == null) 
     evt1.setActivityTimestamp(evt2.getActivityTimestamp()); 

    //TODO: transfer all names from evt2 to evt 1 
    // check if timestamps match, optimize, etc 

    return evt1; 
} 

public static DisplayEvent fromEvent(Event evt) 
{ 
    DisplayEvent dispEvt = new DisplayEvent(); 

    //todo copy the necessary stuff to dispEvt 

    return dispEvt; 
} 

然後拉姆達可能看起來像這樣:

Collection<DisplayEvent> displayEvents = 
       events.stream().collect(Collectors.groupingBy(
         ev -> ev.activityTimestampProperty(), 
         Collectors.reducing(
             new DisplayEvent(), 
             DisplayEvent::fromEvent, 
             DisplayEvent::combine))).values(); 

聲明:我不太喜歡這個:-)所以我個人會堅持一個非DisplayEvent解決方案。

+0

您的解決方案提供給我什麼我開始很遺憾。感謝您的輸入,但我正在尋找將其重複數據放入單個列表中。我使用了一個foreach並以這種方式進行了轉換 - 這解決了我的問題。 –

+0

好吧,也許這是我的錯,因爲我應該在我提出的解決方案中包含DisplayEvent。我又試了一次。查看更新 –

+0

沒想到用reduce。會給它一個鏡頭。謝謝。 –

0

這是我的解決方案,但它並不完全是我希望的lambda表達式。

events 
    .stream() 
    .collect(Collectors.groupingBy(ev -> ev.activityTimestampProperty().get())) 
    .forEach((key,v) -> { 
     DisplayEvent de = new DisplayEvent(); 
     de.activityTimestamp.set(key); 
     for (Event event : v) { 
      de.userName.set(event.getUserName()); 
      de.eventDescriptions.add(event.getEventDescription()); 
      de.eventNames.add(event.geEventName()); 
     } 
     displayActivities.add(dha); 
    });