简体   繁体   中英

Java add some value into Map<…, ?>

I got an somehow annoying problem at work. I have to change some types of one of our APIs, and therefore I've to deal with something like that

List<Map<String, ?>>.

So, all in all it is statisfying in 99.8 % of all cases. But there're a very few positions in our where I've to add some new entries into to the inner maps.

So here's my question, is there're a simple way to add an new entry into a MapObject, typed like follows:

Map<string, ?>

w/o annoying casting waves.

=====EDIT=====

I just came up with a solution myself. I simply use the copy-Constructor of Map, alter the copy and throw away the original. Which is in my case ok, because these maps are just lines of a database-table, which shouldn't be too long/big.

But I'm still curious, if there're better ways to do this. Please tell me, if you know a better to accomplish this.

As described in the Oracle tutorials for Unbounded Wildcards you can only insert null in to an Unbounded Wildcard:

It's important to note that List<Object> and List<?> are not the same. You can insert an Object, or any subtype of Object, into a List<Object>. But you can only insert null into a List<?>. The Guidelines for Wildcard Use section has more information on how to determine what kind of wildcard, if any, should be used in a given situation.

By just using the wildcard type you are explicitly stating that it is a Map with a type but that type is unspecified. It simply isn't safe to add to this Map because the compiler isn't aware what type it contains.

If you are happy adding null to the wildcarded type then you can do that:

private void addToMap(List<Map<String,?>> l){
    l.get(0).put("String",null);
}

The idea of generics is to introduce class type safety at compile time rather than relying on runtime ClassCastExceptions so if lots of casting is required to get your implementation to work you should take a good look at this. Using a copy constructor to get around this also isn't a good idea because that uses an unchecked assignment.

This is an example of leaving broken windows . Don't do this. If the types being returned are too generic then fix the types, don't build on top of them. What you probably should be doing is modifying your method parameter types. I find it hard to believe that the construct making the call expects your method to handle a Map<String,?>. You should at the very least be using Map<String,Object>.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM