java - Retrieve fixed number of entries around an entry in a map sorted by values -
the pojo viz. entry.java represents entry in leaderboard. position position in leaderboard, 1 being user highest score
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 + "]"; } }
these entries stored in map in class shown below :
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 : map of uid-entry */ leaderboarduserentrymap.entryset().stream().sorted(map.entry.comparingbyvalue(comparator.comparing(entry::getscore, integer::compare).reversed())) .filter(/*what put here*/); return null; } }
the method getleaderboard() supposed return
max 2 entries have larger score user (the users above user in leaderboard), user’s own entry , max 2 entries after user in leaderboard
.
i couldn't figure out predicate use return 5 entries, including 1 being searched for. aspect performance since leaderboard can have hundreds of thousands of entries.
**********edit-1**********
the following snippet provided @nullpointer trick have points on mind
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);
note : leaderboarduserentrymap can have millions of entries
the indexofnewentry , +- 2 can cause indexoutofboundsexception, guarding against seems bit tedious, optimal ways here?
will using parallelstream() cause problems ?
list entries = leaderboarduserentrymap.entryset().parallelstream().sorted(map.entry.comparingbyvalue(comparator.comparing(entry::getscore, integer::compare).reversed())).parallel(). map(map.entry::getvalue).collect(collectors.tolist());
stream#limit
shall restrict finding top n
(5) users on reversed list you've created , further can map list> using values , collect list<entry>
as:
return leaderboarduserentrymap.entryset().stream() .sorted(map.entry.comparingbyvalue(comparator.comparing(entry::getscore, integer::compare).reversed())) .limit(5).map(map.entry::getvalue).collect(collectors.tolist());
edit: @yogesh use case
say there 100 users, , user being searched @ 93. list should return 91, 92, 93, 94, 95. solution return 1, 2, 3, 4, 5
since use case have sublist
around current entry, modified as:
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);
edit 2:
the indexofnewentry , +- 2 can cause indexoutofboundsexception, guarding against seems bit tedious, optimal ways here?
since index
of entry might vary on score, , sublist
access further relies on number of output desired before/after it. guarding shall better option other. considered customsublist implementation internally check collection type. how use sublist() explains top voted answers. liked 1 though :
datalist.sublist(math.max(0, first), math.min(datalist.size(), last) );
will using
parallelstream()
cause problems?
unless there synchronized
blocks executed might alter , make concurrent updates stream wouldn't cause problems.
but should know when use parallel stream - should use parallel stream when possible?
Comments
Post a Comment