我需要对以下类型的List中的值进行比较;
List<org.bson.Document>
数据是一个Bson文档,有两个关键:值对(名称和分数)。我需要遍历此列表并删除每个高尔夫球手所做的最低分数。所以,如果Joe打了两场比赛,第一场比赛得分72,第二场比赛得分86,因为这是高尔夫,86是两个得分中的较低者,我需要从列表中删除得分的元素86.这将为每位高尔夫球手留下两者中的较高者,然后让我比较高分(较低的数值)。
使用Java 1.8的任何新功能执行此操作的最佳方法是什么,或者我将不得不复制列表,然后将列表A中的元素x与列表B中的元素x + 1进行比较(在正确排序之后)名字相等?
答案 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);