【发布时间】:2018-02-20 16:56:15
【问题描述】:
POJO 即。入口.java 代表排行榜中的一个条目。 Position 是排行榜中的位置,1是得分最高的用户
public class Entry {
private String uid;
private int score;
private int position;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + score;
result = prime * result + ((uid == null) ? 0 : uid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (!(obj instanceof Entry))
return false;
Entry other = (Entry) obj;
if (score != other.score)
return false;
if (uid == null) {
if (other.uid != null)
return false;
} else if (!uid.equals(other.uid))
return false;
return true;
}
@Override
public String toString() {
return "Entry [uid=" + uid + ", score=" + score + ", position=" + position + "]";
}
}
这些条目存储在一个类中的 Map 中,如下所示:
public class GameDefault {
Map<String, Entry> leaderBoardUserEntryMap;
public void submitScore(String uid, int score) {
Entry newEntry = new Entry(uid, score);
leaderBoardUserEntryMap.put(uid, newEntry);
}
public List<Entry> getLeaderBoard(String uid) {
/* Option-3 : A Map of uid-Entry */
leaderBoardUserEntryMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.comparing(Entry::getScore, Integer::compare).reversed()))
.filter(/*What to put here*/);
return null;
}
}
getLeaderBoard() 方法应该返回
最多两个条目得分大于用户(用户 在排行榜中的用户上方),用户自己的 entry 和 max 两个紧跟在用户之后的条目 排行榜
.
我不知道使用谓词来准确返回 5 个条目,包括正在搜索的条目。另一个方面是性能,因为排行榜可以有数十万个条目。
**********Edit-1**********
@nullpointer 提供的以下 sn-p 可以解决问题,但我有一些想法
List<GameEntry> selectedEntries = leaderBoardUserEntryMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.comparing(GameEntry::getScore, Integer::compare)
.reversed())).map(Map.Entry::getValue).collect(Collectors.toList());
int indexOfnewEntry = selectedEntries.indexOf(leaderBoardUserEntryMap.get(uid));
return selectedEntries.subList(indexOfnewEntry-2,indexOfnewEntry+2);
注意:leaderBoardUserEntryMap 可以有数百万个条目
indexOfnewEntry 和 +- 2 会导致IndexOutOfBoundsException,防范起来似乎有点繁琐,这里有什么最佳方法吗?
-
使用 parallelStream() 会导致问题吗?
列表条目 = leaderBoardUserEntryMap.entrySet().parallelStream().sorted(Map.Entry.comparingByValue(Comparator.comparing(Entry::getScore, Integer::compare).reversed())).parallel()。 map(Map.Entry::getValue).collect(Collectors.toList());
【问题讨论】:
-
如果我对您的理解正确,您正在尝试使用您的自定义比较器返回顶级玩家的 5 个元素的列表!您是否在流中尝试过.limit(5) 方法
-
P.s 你不需要过滤器,因为你返回的是一个排序的流!您只需要将检索到的元素数量限制为 5,然后使用收集器返回一个列表。如果你明白了,请告诉我;如果没有,我可以添加答案;欢呼
-
不,它不是前 5 个条目。虽然集合应该按分数降序排序,但找到一个与 uid 相关的条目,然后检索上面的 2 个和下面的 2 个并返回所有 5 个。检查答案上的 @yogesh 的 cmets
标签: java collections java-8 java-stream