3

I use the following LinkedHashMap and get the occurences of numbers as <number, occurences>.

Map<Integer, Integer> map = new LinkedHashMap<>();

The values stored in the map are as in the following:

key | value
4   | 2
10  | 2
5   | 1
3   | 1

I want to get the first key that has value of 1 (in the example, it is 5). If there is not a key that has value of 1, it returns -1. I use the following approach, but I think it is not a proper way and there may be a better or short way to do this:

int key = map.containsValue(1) ?
                map.entrySet().stream()
                   .filter(entry -> entry.getValue() == 1)
                   .map(Map.Entry::getKey).findFirst().get() : -1;

So, is there a better way to achieve this?

1 Answers1

1

Rather than checking containsValue first, use orElse on the optional returned by findFirst, which is one fewer iteration through the map.

int key = map.entrySet().stream()
               .filter(entry -> entry.getValue() == 1)
               .map(Map.Entry::getKey).findFirst().orElse(-1);

findFirst would return an empty optional if there is nothing left after the filter. This only happens if there is no value 1 in the map to begin with. orElse returns its argument, if the optional is empty, otherwise it returns the wrapped value.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • That is exactly what I am looking for, thanks a lot amigo voted up. On the other hand, I also used `map.getOrDefault` method for another place like `int value = map.getOrDefault(key, 0) + 1;` In this part, I want to increase the value of the key by 1 (if the key is not present in the map, it starts from 0 and I add +1). So, is there also a better way for `getOrDefault` in this example? –  May 24 '22 at 09:52
  • @stack You want to get a key from a value, rather a value from a key here, so `getOrDefault` does not help. :( – Sweeper May 24 '22 at 09:57
  • Noo, I asked it for `int value = map.getOrDefault(key, 0) + 1;` part only. In this example I want to check if the key exists and increase its value by 1 (if not exists, set it to 1). So, any suggestion for this part? –  May 24 '22 at 10:00
  • Thanks a lot, exactly. But I could not understand how should I replace the last parameter for my example: `int value = map.merge(key, 1, Integer::sum)` or another usage is `map.merge(key, 1, (a,b) -> a+b);`. Any idea? –  May 24 '22 at 10:10
  • I checked, but cannot convert `int value = map.getOrDefault(key, 0) + 1;` by using `map.merge` e.g. `int value = map.merge(key, 1, ???? )`. So, what should be the last parameter denoted by "????" –  May 24 '22 at 10:20
  • @stack Oh I think I understand now. You *don't* want to modify the map? Then just keep using `int value = map.getOrDefault(key, 0) + 1;`. I see nothing that needs to be changed. In any case, what does this have to do with the original question you posted? If you have a different problem, please post another question. – Sweeper May 24 '22 at 10:28
  • Ok amigo, marked this reply as answer and opened a new question on https://stackoverflow.com/questions/72361400/how-to-increase-hashmap-value-using-merge-method-in-java –  May 24 '22 at 10:36