Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check types of key and value if Object instanceof HashMap?

I have a method that accepts an Object. In one use case, the method accepts a HashMap<String, String> and sets each value to the property of the corresponding key name.

public void addHelper(Object object) {
    if (object instanceof HashMap) {
        HashMap<String, String> hashMap = (HashMap<String, String>) object;
        this.foo = hashMap.get("foo");
        this.bar = hashMap.get("bar");
    }
}

This class adheres to a particular interface, so adding setters for those properties is not an option.

My question is, how can I check the type cast here?

HashMap<String, String> hashMap = (HashMap<String, String>) object;

Thanks in advance!

SOLUTION

Thanks to the answer from @drobert, here is my updated code:

public void addHelper(Object object) {
    if (object instanceof Map) {
        Map map = (Map) object;
        if (map.containsKey("foo")) this.foo = map.get("foo").toString();
        if (map.containsKey("bar")) this.bar = map.get("bar").toString();
    }
}
like image 252
Shaun Scovil Avatar asked Oct 03 '13 15:10

Shaun Scovil


People also ask

How do you check if an object is in a HashMap?

HashMap containsKey() Method in Java containsKey() method is used to check whether a particular key is being mapped into the HashMap or not. It takes the key element as a parameter and returns True if that element is mapped in the map.

Can HashMap have different value types?

Yep Sure.. please find the edited answer.. The example is only all about how to add,search, retrieve values in HashMap.


3 Answers

You can't. Due to type erasure, reflection will show you have an instance of HashMap, but the types are dropped at runtime. Effectively, you have HashMap< Object,Object >.

That said, you still have some options, and some advice I'd suggest you take. Among them:

  • Check to see if it's an instance of 'Map' rather than 'HashMap'. It will make your API much more flexible since you most likely only care that you have rapid access by key rather than any particular impementation
  • Take advantage of java.util.Map's api which defines 'containsKey(Object)' and 'get(Object)', so you can still use mapInst.get("stringKey") safely, even without having to cast.
  • You can't ensure all values are strings, but you can take advantage of java.lang.Object's toString() method and obtain a String for each value regardless.

In short: treat this like any Map, and attempt to access the keys as Strings even without the cast, and attempt to utilize each value as a String by doing a null check then calling .toString() and you'll have a much safer implementation.

like image 178
drobert Avatar answered Oct 21 '22 09:10

drobert


It should be noted that the original routine is exactly equivalent to coding

public void addHelper(Object object) {
    if (object instanceof HashMap) {
        HashMap hashMap = (HashMap) object;
        this.foo = (String)(hashMap.get("foo"));
        this.bar = (String)(hashMap.get("bar"));
    }
}

The explicit (HashMap) cast cannot possibly throw an error, since it's guarded by the instanceof. The implicitly-supplied (String) casts will only throw an error if the values returned from the HashMap are not Strings (or nulls).

(By "exactly equivalent to" I mean that the same bytecode is produced.)

like image 45
Hot Licks Avatar answered Oct 21 '22 10:10

Hot Licks


You should use try-catch, where you call addHelper(Object) method. This will ensure your correct type of HashMap.

      try{
        addHelper(hashMap);
        }
        catch(ClassCastException ex){
            System.out.println("Is not desired hashmap");
        }
like image 36
Masudul Avatar answered Oct 21 '22 09:10

Masudul