对复合对象列表进行分组

时间:2017-01-27 13:49:57

标签: java arraylist java-8

我有一个ArrayList(Result),其中Result对象都拥有对Event对象的引用。 ArrayList中可能有50个Result对象,但只有5个不同的Event对象。有没有办法循环遍历ArrayList并将具有相同Event.getName()引用的结果组合在一起?

我想在“跳高”事件中分别对结果运行一个方法,然后仅在事件“跳远”等结果中运行结果。 我事先不知道结果列表中的哪些事件是从用户输入创建的。

我知道如何在事件名称上对ArrayList进行排序,但我想更确切地按事件拆分列表并将它们存储在其他临时列表中(?)

来自Result class:

public Result(double result, int attemptNumber, Participant participant, Event event) {
    this.result = result;
    this.attemptNumber = attemptNumber;
    this.participant = participant;
    this.event = event;
}
来自Event class的

public Event (String eventName, int attemptsAllowed) {
    this.eventName = eventName;
    this.attemptsAllowed = attemptsAllowed;
}

public String getEventName() {
    return eventName;
}

结果对象在名为allResults的ArrayList中未排序存储,这是第三个类中的一个方法,它根据输入eventName对allResults(称为resultByEvent)的副本进行排序和修剪,并且每个参与者只保留最高结果:

public ArrayList<Result> resultsByEvent(String eventName) {
    resultsByEvent.addAll(allResults);

    for(int i = 0; i < resultsByEvent.size(); i++) {
        Event event = resultsByEvent.get(i).getEvent();

        if(!event.getEventName().equals(eventName)) {
            resultsByEvent.remove(i);
        }
    }

    Collections.sort(resultsByEvent, new EventLeaderboard());

    for(int n = 0; n < resultsByEvent.size(); n++) {
        for(int j = n + 1; j < resultsByEvent.size(); j++) {
            Participant participant1 = resultsByEvent.get(n).getParticipant();
            Participant participant2 = resultsByEvent.get(j).getParticipant();

            if(participant1.getParticipantId() == participant2.getParticipantId()) {
                resultsByEvent.remove(j);
                j = j - 1;
            }
        }
    }
    return resultsByEvent;
}

以上是我想在原始结果列表中的所有事件上运行的内容。

3 个答案:

答案 0 :(得分:4)

您可以使用Stream API执行此操作:

按名称分组活动

Map<String, List<Event>> eventsGroupedByName = allResults.stream().collect(
                Collectors.groupingBy(e -> e.getEvent().getName()));

按活动名称分组结果

Map<String, List<Result>> resultsGroupedByEventName = allResults.stream().collect(
                Collectors.groupingBy(r -> r.getEvent().getName()));

答案 1 :(得分:3)

您可以创建“事件名称”/“相应结果列表”的 eventsResults Map,然后当您查找与某个名称匹配的结果时,只需调用{{1} }。

在以下示例中,List<Result> matchingResults = eventsResults.get(<some event name>)results

List<Result>

答案 2 :(得分:0)

你可以做一个列表地图。 Key = reference,data =该类型引用的列表。