51

I'm using the following code for checking if a key exists in a Map instance:

if (!map_instance.containsKey(key))
    throw new RuntimeException("Specified key doesn't exist in map");
else
   return map_instance.get(key);

My question is:

Is there a utility or Map implementation to simplify the above code, such as:

custom_map.get(key,"Specified key doesn't exist in map");

My goal is: if key does not exist in map, the map implementation throws an exception with the passed string.

I don't know whether or not my desire is reasonable?

(Sorry if I am using the wrong terminology or grammar, I am still learning the English language.)

Noel Yap
  • 18,822
  • 21
  • 92
  • 144
Sam
  • 6,770
  • 7
  • 50
  • 91
  • 1
    Little hint to your code: `return true;` in your else block instead of `return map_instance.containsKey(key);`, another invocation of that method is redundant (if this code is used only by one thread at a time) – Pshemo Jul 08 '12 at 14:06
  • @Pshemo OP in fact wants to implement `get` this way, so just the name of the method called is wrong. – Marko Topolnik Jul 08 '12 at 14:07
  • @MarkoTopolnik You are probably right, but just in case I will leave that comment so OP can notice that there is something to improve there. – Pshemo Jul 08 '12 at 14:17

6 Answers6

61

I use Optional Java util class, e.g.

Optional.ofNullable(elementMap.get("not valid key"))
            .orElseThrow(() -> new ElementNotFoundException("Element not found"));
JeremyW
  • 5,157
  • 6
  • 29
  • 30
Sir Montes
  • 882
  • 1
  • 7
  • 18
  • 9
    I think that's the best solution. But better use `NoSuchElementException` – Herr Derb Mar 18 '20 at 08:41
  • 2
    Good proposal, but it doesn't work when the map has an entry with null as a key on the map.as it would throw the exception rather than returning the associated value. – avalori Jun 13 '20 at 17:27
  • 3
    This totally works, however, it's an abuse of the `Optional` data type per its author: https://stackoverflow.com/a/26328555 Optional is to be used as a return type, not as a way to branch through chaining in operational code. – TodoCleverNameHere Jan 20 '22 at 19:24
29

There is one more nice way to achieve this:

return Objects.requireNonNull(map_instance.get(key), "Specified key doesn't exist in map");

Pros:

  • pure Java - no libs
  • no redundant Optional - less garbage

Cons:

  • only NullPointerException - sometimes NoSuchElementException or custom exceptions are more desirable

Java 8 required

Evgeny Kharitonov
  • 947
  • 11
  • 12
22

In Java 8 you can use computeIfAbsent from Map, like this:

map.computeIfAbsent("invalid", key -> { throw new RuntimeException(key + " not found"); });
  • 72
    Don’t do this. "computeIfAbsent" is meant as a mutation operation. So if your map happens to be an UnmodifiableMap, or a Guava or Eclipse Collection ImmutableMap, or a ProtoMap, this call will immediately fail with some sort of UnsupportedOperationException. A Java8 equivalent could be: `Optional.fromNullable(map.get("invalid")).orElseThrow(() -> new RuntimeException(key + " not found"));` This has slightly more bloat, but has the advantage of correctness. – monarch_dodra Sep 12 '18 at 15:24
  • 2
    Great comment. But the proposed alternative doesn't work when there is an entry with null as a key on the map, as it would throw the exception rather than returning the associated value. – avalori Jun 13 '20 at 17:28
7

You could take a look into the configuration map from Apache commons. It doesn't implements Map, but has a similar interface with a few Helper methods, like getString, getStringArray, getShort and so on.

With this implementation you could use the method setThrowExceptionOnMissing(boolean throwExceptionOnMissing) and could catch it and handle as you want.

Isn't exactly with a configurable message but from my point of view it doesn't make sense to throw a fixed exception just with a custom message since the exception type itself depends on the context where the get method is invoked. For example, if you perform a get of an user the exception would be something related to that, maybe UserNotFoundException, and not just a RuntimeException with the message: User not Found in Map!

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • Thanks for your answer, can you show a sample?I don't familiar with `Apache Common Configuration`. – Sam Jul 09 '12 at 08:42
  • 2
    `MapConfiguration mc = new MapConfiguration(properties); mc.setThrowExceptionOnMissing(true); mc.getString("key");` if key doesn't exists a `NoSuchElementExcpetion` will be thrown – Francisco Spaeth Jul 09 '12 at 08:48
2

Such a method does not exist for a Map in Java. You could create it by extending the Map class of course or by creating a wrapper class that contains the map and a tryGet method.

C# however does have a such a method: Directory.TryGetValue()

public class MyMap {
    public Map<Object, Object> map = new HashMap<Object, Object>();

    public Object tryGet(Object key, String msg) {
        if(!map.containsKey(key))
           throw new IllegalArgumentException(msg);
        return map.get(key); 
   }
mort
  • 12,988
  • 14
  • 52
  • 97
0

the way you are doing it is the way to go.

as a side note, your code doesn't make much sense since you will always return true, maybe you meant:

return map_instance.get(key);
Tomer
  • 17,787
  • 15
  • 78
  • 137