比较同一列表的两个列表元素之间的值

时间:2015-08-17 21:35:06

标签: java list arraylist lambda comparison

我需要对以下类型的List中的值进行比较;

List<org.bson.Document>

数据是一个Bson文档,有两个关键:值对(名称和分数)。我需要遍历此列表并删除每个高尔夫球手所做的最低分数。所以,如果Joe打了两场比赛,第一场比赛得分72,第二场比赛得分86,因为这是高尔夫,86是两个得分中的较低者,我需要从列表中删除得分的元素86.这将为每位高尔夫球手留下两者中的较高者,然后让我比较高分(较低的数值)。

使用Java 1.8的任何新功能执行此操作的最佳方法是什么,或者我将不得不复制列表,然后将列表A中的元素x与列表B中的元素x + 1进行比较(在正确排序之后)名字相等?

5 个答案:

答案 0 :(得分:1)

我对bson不熟悉,所以我尝试获得一个名字,得分条目的流程是这样的:

List<org.bson.Document> ldoc = new ArrayList<>();
Stream<Entry<String, Integer>> s
            = ldoc.stream()
            .flatMap(d -> d.entrySet().stream())
            .map(e -> new AbstractMap.SimpleImmutableEntry<String,Integer>(e.getKey(),((Integer)e.getValue())));

我直接从列表中创建了Stream。

List<Entry<String, Integer>> l = new ArrayList<>();
    l.add(new AbstractMap.SimpleImmutableEntry<>("Joe", 72));
    l.add(new AbstractMap.SimpleImmutableEntry<>("Joe", 66));
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 73));
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 86));
    l.add(new AbstractMap.SimpleImmutableEntry<>("John", 99));

可以像这样在同一个流中进行分组和最小化:

Map<String, Optional<Integer>> m = l.stream()
            .collect(Collectors.groupingBy(e -> e.getKey(),
                            Collectors.mapping(e -> e.getValue(),
                                    Collectors.minBy((i1, i2) -> Integer.compare(i1, i2)))));
System.out.println("m = " + m);

这产生了输出:

m = {Joe=Optional[66], John=Optional[73]}

这是每个球员按名称得分最低的地图。

获得胜利者:

String winner = m.entrySet()
            .stream()
            .min((e1, e2) -> Integer.compare(e1.getValue().get(), e2.getValue().get()))
            .get().getKey();
System.out.println("winner = " + winner);

打印哪些:

winner = Joe

答案 1 :(得分:0)

你必须使用List吗? 尝试使用hashMap,这样你就可以检查你想要在hashMap中插入的玩家是否已经存在,如果是这样,你可以查看他的得分,如果情况更糟,你会覆盖它。 之后,你应该获得得分最高的玩家的hashMap。

编辑: 我的坏..我没有正确地阅读你的问题。您必须使用bson.Document数据类型。在这种情况下,您可以使用treeSet并定义自定义比较器,如果两个元素(播放器)具有相同的名称,则返回0(true)。然后,您可以在原始答案中应用与写入相同的logis。

答案 2 :(得分:0)

我真的不知道1.8,但我只是比较同一个列表中的条目,而不创建第二个条目。我会这样做(用伪方法,我不知道bson):

for (int i=0; i<List.length;i++) {
    int bestScore = List.getElementAt(i).getScore();
    int bestLocation = i;
    String currname = List.getElementAt(i).getName();
    for (int j=i+1;i<List.length;j++) {
        if (List.getElementAt(j).getName().equals(currname)) {
            if (List.getElementAt(j).getScore()<bestScore) {
                List.removeElementAt(bestLocation);
                bestScore = List.getElementAt(j).getScore();
                bestLocation = j;
            } else {
                List.removeElementAt(j);
                j--;
            }
        }
    }
}

...或者排序。认为你明白我的想法。您可能需要注意这可能导致的一些错误,但我希望我可以帮助您解决这个问题。

此外,由于List.length更改此功能可能无法正常工作,但可以在删除某些内容时将其添加到代码中。

答案 3 :(得分:0)

我不确定你的问题。但是我从描述中理解,我建议你使用HasMap&gt;。

通过这种方式,您可以为每位玩家分类值,并可以轻松删除最低分!

答案 4 :(得分:0)

如果您知道在整个文档中迭代分数的方法,则可以按升序对列表进行排序。排序后,您可以从列表中删除最后一个元素。有许多方法可以对列表进行排序。一些主要的是冒泡排序和选择排序。

您还可以查找最大值的索引并删除该元素。这种方法更容易,更有效。我还会给你一个这个方法的伪代码。在代码中,列出您指定的Array列表的名称。

int max = list.get(0);
index = 0;
for(int i = 1; i < list.size(); i++)
{
if(list.get(i) > max)
{
max = list.get(i);
index = i;
}
}
list.remove(i);