对对象的arraylist进行分组并在java中获取每组的最大值

时间:2018-01-03 21:21:08

标签: java sorting arraylist grouping

我有一个名为ResultList的arraylist。这个arraylists由对象(Results)组成,对象又引用Participant对象和Competition对象作为属性。我需要做的是按参与者对这个arraylist(ResultList)进行分组,然后将每个参与者的最大结果(度量)放在一个新列表中。

结果类:

public class Result {

private double measurement;
private int participantID;
private Participant participant;
private Competition competition;

public Result(double measurement, int participantID, Competition competition, Participant participant) {
    this.measurement = measurement;
    this.participant = participant;
    this.competition = competition;
}

参与者课程:

public class Participant {

private String firstName;
private String lastName;
private int id;
private String gender;
private String teamName;

public Participant(String firstName, String lastName, int id, String gender, String teamName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.id = id;
    this.gender = gender;
    this.teamName = teamName;
}

最后我有ResultList类:

public class ResultList {

private Scanner sc;

private String listName;
private ArrayList<Result> resultList = new ArrayList<Result>();

public ResultList(Scanner sc, String name) {
    this.sc = sc;
    this.listName = name;
}

在ResultList类中,我有一个方法来使用比较器对列表进行排序,在迭代完毕后查找特定竞争的结果:

public void listResultsForCompetition(String competitionName) {
Iterator<Result> it = resultList.iterator();
boolean nothingFound = true;
ArrayList<Result> tempResultList = new ArrayList<Result>();
while (it.hasNext()) {
    Result nextItem = (Result) it.next();
    if (nextItem.getCompetitionName().equalsIgnoreCase(competitionName)) {
        nothingFound = false;
        tempResultList.add(nextItem);
    }
}
    if (nothingFound) {
        System.out.println("Error: No results found for this event. ");
    }
    Collections.sort(tempResultList, Result.ResultComparatorMeasurement);

}

所以现在我有了一个名为tempResultList的arraylist,它具有&#34;测量&#34;所定义的特定比赛的所有结果。 Result对象中的属性。我现在需要做的是以某种方式从tempResultList中的每个参与者获得最高结果,并将其存储在另一个列表中,以便为参与者生成特定竞赛的最佳结果列表。

我已经搜索了几个小时,但我无法理解我找到的答案,因为他们中的大多数只有一个简单的整数列表或类似的。我已经看过多次对地图,流和收集方法的引用,但我无法理解它。

编辑:arraylist中没有固定数量的结果或参与者。

1 个答案:

答案 0 :(得分:0)

如果您必须排序某些内容,List不是该集合的完美匹配。根据结果​​,您必须选择最佳集合。

在您的示例中,我看不出您要如何使用List<Result> tempResultList。看来,您使用的只是作为临时收集来实现主要目标 - 获得所有参与者的最高结果。但我可以看到以下内容:

首先:您已经拥有List<Result> tempResultList 已排序结果(开头的最佳结果)。您只需迭代此列表,并为每个参与者获得第一个结果:

Map<Integer, Result> topResults =  new LinkedHashMap<>();

for(Result result : tempResultList) {
    if(!topResults.containsKey(result.getParticipant().getId()))
        topResults.put(result.getParticipant().getId(), result);
}

注意: hree我通过您的tempResultList并填写了地图,其中key是参与者的ID和值 - 参与者的结果。如果参与者不在地图中,则将其结果添加到地图中(排序列表中的第一个将是最高结果)。您可以使用此处LinkedHashMap根据tempResultListTreeMap中的上诉对地图中的键进行排序,以按参与者的ID对其进行排序。甚至 - &#39; HashMap&#39;,当您不关心topResults.values()的订单时。

第二:您可以使用tempResultList构建Map<Integer, Set<Result>> res,然后同时对排名最高的结果进行排序。您已经有一个比较器需要Result.ResultComparatorMeasurement。地图的关键 - 是参与者的ID,值 - 参与者结果的排序列表,首先是最佳结果。

public List<Result> listResultsForCompetition(String competitionName) {
    Map<Integer, Set<Result>> participantResults = new HashMap<>();

    for (Result result : resultList) {
        int participantId = result.getParticipant().getId();

        if (!participantResults.containsKey(participantId))

// TreeSet将根据给定的比较器对结果进行排序(前面的结果)                 participantResults.put(participantId,new TreeSet&lt;&gt;(Result.ResultComparatorMeasurement));

        participantResults.get(participantId).add(result);
    }

    Map<Integer, Result> topParticipantResults = new HashMap<>();

    for (Map.Entry<Integer, Set<Result>> entry : participantResults.entrySet())
        topParticipantResults.put(entry.getKey(), entry.getValue().iterator().next());

    List<Result> topResults = new ArrayList<>(topParticipantResults.values());

    return topResults;
}

注意:我这里不使用stream API来使其最大限度地清除。我使用TreeSet<Result>(comparator)来接收一组排序的结果(注意!!! - Set使用比较器进行罚款并排除重复,因此您的比较器不仅应该比较结果,还要在两个Result实例具有相同测量值的情况下正确工作。 Map<Integer, Set<Result>> participantResults包含按参与者ID分组的所有结果。

还有其他方法可以解决这个问题。我只给了你2个想法。