2

I have already looked at sorting a HashMap by value here but I'm not quite sure how to extract top 'n' entries of this sorted HashMap. Or is there a better way of accomplishing this?

To provide some overview, I'm working on a P2P project and I maintain a mapping between peerID and the corresponding rate at which files can be downloaded from each of those peers. Then I need to select top 'n' peers with highest download rates.

tinkuge
  • 97
  • 1
  • 11
  • 2
    Your question is unclear. Once you have the `LinkedHashMap` in the correct order, just iterate over the values and take the first (or last depending on the sort order) _n_ entries. – Jim Garrison Nov 23 '17 at 00:39
  • https://stackoverflow.com/a/23846961/1553851 – shmosel Nov 23 '17 at 00:39
  • You should review https://stackoverflow.com/q/109383/18157 as wel – Jim Garrison Nov 23 '17 at 00:40
  • 2
    You might consider using [PriorityQueue](https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html) over sorting `HashMap`. – Aivean Nov 23 '17 at 00:41

2 Answers2

5

Obviously a TreeMap with a custom comparator would be a better choice, especially since it has a method that is specifically tailored for this: headMap(Key k) which will give you all the entries up to this key.

On the other hand if you insist on the HashMap you could use java-8 for this:

yourMap.entrySet()
       .stream()
       .sorted(Comparator.comparing(e -> e.getValue(), Comparator.reverseOrder()))
       .limit(n)
       .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Eugene
  • 117,005
  • 15
  • 201
  • 306
  • Hi Eugene! You know, there's no method that returns the top/bottom n entries in TreeMap. tailSet and headSet return a subset view that is either higher than or lower than the given value. You have to go the stream way for this, there's no other option. – fps Nov 23 '17 at 18:26
  • @FedericoPeraltaSchaffner there is something I am missing probably in your comment... I am referring to `headMap` and it does return a view indeed... isn't what the OP is asking for here? – Eugene Nov 23 '17 at 20:42
  • Hey Eugene. My point is that there's no way to select top n entries from a TreeMap, with n being a fixed number. headSet returns a view of the entries lower than a given value (not lower than a given index). That was my point. You'll find that there's no straightforward way to return a submap view of fixed size; you have to stream the entries and use limit(n) and collect to a new map. (This is why I have upvoted your answer). – fps Nov 23 '17 at 20:47
  • @DachuanZhao am I supposed to guess what is happening from your comment? – Eugene Aug 04 '21 at 03:29
2

I think you might consider using the TreeSet class instead of the HashMap so you can always have them sorted. To access the 'n' you could use the Iterator or the subSet(), tailSet() methods, depending on what you need.

  • 1
    There's no method that returns the top n entries, neither in TreeSet nor in TreeMap. tailSet and headSet return a subset view that is either higher than or lower than the given value. – fps Nov 23 '17 at 18:24