19

I wrote following method to find the keys mapped to the highest values and trying to convert to java Streams. Can you please help?

private List<Integer> testStreamMap(Map<Integer, Long> mapGroup) 
{
    List<Integer> listMax = new ArrayList<Integer>();
    Long frequency = 0L;
    for (Integer key : mapGroup.keySet()) {
        Long occurrence = mapGroup.get(key);
        if (occurrence > frequency) {
            listMax.clear();
            listMax.add(key);
            frequency = occurrence;
        } else if (occurrence == frequency) {
            listMax.add(key);
        }
    }
    return listMax;
}
Eran
  • 387,369
  • 54
  • 702
  • 768
Dumy
  • 193
  • 1
  • 1
  • 6
  • 2
    Your question is not clear, the same parameter that you called `occurance`( which is misspelled btw) is called in the second implementation `tempValue`. And the parameter that you named `frequencey` (which is also misspelled) in the first implementation is called `occurrence` in the second. Start by being consistent with your names and that might help you solve your confusion. – Nir Alfasi Feb 06 '17 at 04:35
  • 1
    "Key with highest occurrence"?, I guess you are trying to find out the "value" with highest occurrence as you are calling `mapGroup.get(key)`. Correct? – Shyam Baitmangalkar Feb 06 '17 at 04:36
  • @ShyamBaitmangalkar yes, Try to find out the key list with highest occurrence – Dumy Feb 06 '17 at 07:26

2 Answers2

31

You can get a single key via

Integer max=mapGroup.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey();

but unfortunately, there is no built-in function for getting all equivalent maximums.

The simplest, straight-forward solution is to find the maximum value first and retrieve all keys mapping to that value afterwards:

private List<Integer> testStreamMap(Map<Integer, Long> mapGroup) {
    if(mapGroup.isEmpty())
        return Collections.emptyList();
    long max = mapGroup.values().stream().max(Comparator.naturalOrder()).get();
    return mapGroup.entrySet().stream()
        .filter(e -> e.getValue() == max)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
}

Solutions for getting all maximum values of a stream in a single pass, are discussed in “How to force max() to return ALL maximum values in a Java Stream?”. You will see that single-pass solutions are much more complicated and not worth the effort if your input is an ordinary Map (e.g. HashMap), which can be iterated multiple times cheaply.

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
25

I'm not sure what half your code is trying to do, but to answer your question as per the title, which I'm guessing was meant to be "find the entry with the highest value":

Map.Entry<Integer, Long> maxEntry = map.entrySet().stream()
  .max(Map.Entry.comparingByValue()).get();
Bohemian
  • 412,405
  • 93
  • 575
  • 722