How to get the “test” data from this linkedHashMap
Map<String, Object> response = new LinkedHashMap<String, Object>() {{ put("data", new LinkedHashMap<String, Object>() {{ put("images", new LinkedHashMap<String, Object>() {{ put("original", new LinkedHashMap<String, Object>() {{ put("url", "test"); }}); }}); }}); }};
response.get(“url”) = null
response.get(“data.images.original.url”) = null
response.get(“data”).get(“images”).get(“original”).get(“url”)
Compilation failed: cannot find symbol symbol: method get(java.lang.String) location: class java.lang.Object
toString();
result{data={images={original={url=test}}}};
Advertisement
Answer
The “right” way would be
Object url = ((Map<String,Object>) ((Map<String,Object>) ((Map<String,Object>) response.get("data")).get("images")).get("original")).get("url");
And yes, this is ugly as all heck. Mostly because of the types you’ve chosen.
By making the value of your maps Object
you’ve gained flexibility on what to put in, but you put the burden on the “reader” of the map to actually cast to whatever they want. And since generics are involved all of these casts are unchecked (i.e. the runtime can check that the returned objects are in fact Map
but it can’t verify that they are really Map<String, Object>
.
Additionally, you also make use of double brace initialization, which I’d strongly discourage, because it’s an ugly hack. If you’re using Java 9 or later, then simply use Map.of()
instead:
Map<String, Object> response = Map.of( "data", Map.of( "images", Map.of( "original", Map.of( "url", "test" ) ) ) );
The indentation here is only there to visualize the structure of those calls, it’s absolutely not necessary.