How Can I create a generic HashMap to insert collections and objects? - java

How Can I instantiate a HashMap to put collections and objects?.
//it's wrong
Map<String,?>params=new HashMap<String,? >
List<Person> lstperson=getPerson();
params.put("person",lstperson);
params.put("doc",objectDoc);
params.put("idSol",new Long(5));
service.method(params);
//method
public void method(Map<String, ?> params);

Declare the hash map as
Map<String,Object> params = new HashMap<String,Object>();
You can keep the declaration of
public void method(Map<String, ?> params);
as it is, as long as the method only every tries to read from the map.

All classes in Java extends Object. so you can use Object for a value type in a map, like
Map<String, Object> params = new HashMap<String, Object>

You need to change
Map<String,?>params=new HashMap<String,? >
to like this
Map<String,Object>params=new HashMap<String,Object>()
But its not good practice to put all type of objects into single map. Better you can create POJO and add it to map.

I cam here for substitute in Kotlin
You can declare in kotlin as :-
val map: Map<String, Any?>

Related

How can I combine two HashMap objects containing the different types?

I have two HashMap objects defined as:
Map<String, String> requestParams = new HashMap<>();
Map<String, Boolean> requestParamForOauth = new HashMap<>();
How can I merge these two maps?
Assuming that both maps contain the same set of keys, and that you want to "combine" the values, the thing you would be looking for is a Pair class, see here for example.
You simply iterate one of the maps; and retrieve values from both maps; and create a Pair; and push that in your result map.
The only downside is that there is no "official" Pair class that you could use (see here for more thoughts around that).
Alternatively, if there is a "deeper" meaning of those "combined" values (beyond a simple "tuple/pair" semantics), you could instead create your own class that wraps around those two values.
Your keys are of the same type (String), but the values are not even related by an interface or super class, you will need to define a Map<String, Object> and make use of the Map#putAll method
Map<String, String> requestParams = new HashMap<>();
Map<String, Boolean> requestParamForOauth = new HashMap<>();
Map<String, Object> requestParamForOauth2 = new HashMap<>();
requestParamForOauth2.putAll(requestParams);
requestParamForOauth2.putAll(requestParamForOauth);
If you want to use one list to store all the data You can
use one HashMap<String,Object>
What do you want to do when the same key appears in both Map? If you want to keep both the String and Boolean, then you'll need a map that looks like this: Map<String, Pair(String, Boolean)>. If you just want to keep one value, then Map<String, Object> is what you want.

Casting a HashMap

i´m trying to make a casting of Hasmap
I have this hasmap:
Map<String, Object> requestargs = new Map<String, Object>();
Other side i have a method who bring me a hashmap of: Map<String, Document>
MultipartForm form = MgnlContext.getWebContext().getPostedForm();
The method is getDocuments();
I need to put the return of this method in my hashmap making something like this:
requestargs = form.getDocuments();
But i don´t know how to cast this Hasmap og (String,Document) to (String,Object)
Thanks
Unless you can use a wildcard
Map<String, ? extends Object> requestargs
You will need to copy the map into a new map:
requestargs = new HashMap<String, Object>(form.getDocuments());
The two types are not related directly. Were you able to make the assignment directly (or via casting) it would be possible to insert a value with non-Document type into the map, and that would be type-unsafe:
Map<String, Document> docs = form.getDocuments();
Map<String, Object> requestargs = docs; // not actually allowed
requestargs.put("Foo", new Object());
for (Document doc : docs.values()) {
// doc isn't necessarily a Document! ClassCastExceptions abound.
}
To prevent this problem happening, such an assignment is forbidden by the type system.
The wildcard works because it makes it impossible to call put on the map, since there is no way to know what types can be put into the map safely.

How to create a map instance variable

I've been trying to create a class that will model a scenario I've come up with. It will involve a map with string keys and values.
I need to create an instance variable used to reference the map object, and a constructor that creates the empty map and assigns it to the map instance variable.
I've been messing around with map objects but not creating a class using them, and I've hit a mental block!
What's the proper way to actually get a map object?
public class TheClass {
private Map<String, String> theMap;
public TheClass() {
theMap = new HashMap<>();
}
}
public class Demo {
Map<String,String> map = null;
public Demo()
{
map = new HashMap<String,String>();
}
}
If you want to use HashMap which is Map implementation you can do it like that:
Map<String, String> map = new HashMap<String, String>();
or
Map<String, String> map = new HashMap<>();
in Java 7.
You can also use other implementations like TreeMap.
You can use the HashMap which is an implementation of Map
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Map<String,String> map = new HashMap<String,String>();
map.put("key1", "Value1");
map.put("Key2", "Value2");

Converting Map<String,String> to Map<String,Object>

I have Two Maps
Map<String, String> filterMap
Map<String, Object> filterMapObj
What I need is I would like to convert that Map<String, String> to Map<String, Object>.
Here I am using the code
if (filterMap != null) {
for (Entry<String, String> entry : filterMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
Object objectVal = (Object)value;
filterMapObj.put(key, objectVal);
}
}
It works fine, Is there any other ways by which I can do this without iterating through all the entries in the Map.
Instead of writing your own loop that calls put, you can putAll, which does the same thing:
filterMapObj.putAll(filterMap);
(See the Javadoc.)
And as Asanka Siriwardena points out in his/her answer, if your plan is to populate filterMapObj immediately after creating it, then you can use the constructor that does that automatically:
filterMapObj = new HashMap<>(filterMap);
But to be clear, the above are more-or-less equivalent to iterating over the map's elements: it will make your code cleaner, but if your reason for not wanting to iterate over the elements is actually a performance concern (e.g., if your map is enormous), then it's not likely to help you. Another possibility is to write:
filterMapObj = Collections.<String, Object>unmodifiableMap(filterMap);
which creates an unmodifiable "view" of filterMap. That's more restrictive, of course, in that it won't let you modify filterMapObj and filterMap independently. (filterMapObj can't be modified, and any modifications to filterMap will affect filterMapObj as well.)
You can use the wildcard operator for this.
Define filterMapObj as Map<String, ? extends Object> filterMapObj and you can directly assign the filterMap to it. You can learn about generics wildcard operator
You can simply write
Map<String, Object> filterMapObj = new HashMap<>(filterMap);
You can use putAll method to solve the problem.The Object is the father class of all objects,so you can use putAll without convert.

Converting java.util.Properties to HashMap<String,String>

Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties is a implementation of java.util.Map, And java.util.HashMap's constructor receives a Map type param. So, why must it be converted explicitly?
This is because Properties extends Hashtable<Object, Object> (which, in turn, implements Map<Object, Object>). You attempt to feed that into a Map<String, String>. It is therefore incompatible.
You need to feed string properties one by one into your map...
For instance:
for (final String name: properties.stringPropertyNames())
map.put(name, properties.getProperty(name));
The efficient way to do that is just to cast to a generic Map as follows:
Properties props = new Properties();
Map<String, String> map = (Map)props;
This will convert a Map<Object, Object> to a raw Map, which is "ok" for the compiler (only warning). Once we have a raw Map it will cast to Map<String, String> which it also will be "ok" (another warning). You can ignore them with annotation #SuppressWarnings({ "unchecked", "rawtypes" })
This will work because in the JVM the object doesn't really have a generic type. Generic types are just a trick that verifies things at compile time.
If some key or value is not a String it will produce a ClassCastException error. With current Properties implementation this is very unlikely to happen, as long as you don't use the mutable call methods from the super Hashtable<Object,Object> of Properties.
So, if don't do nasty things with your Properties instance this is the way to go.
You could use Google Guava's:
com.google.common.collect.Maps.fromProperties(Properties)
How about this?
Map properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);
Will cause a warning, but works without iterations.
The Java 8 way:
properties.entrySet().stream().collect(
Collectors.toMap(
e -> e.getKey().toString(),
e -> e.getValue().toString()
)
);
Properties implements Map<Object, Object> - not Map<String, String>.
You're trying to call this constructor:
public HashMap(Map<? extends K,? extends V> m)
... with K and V both as String.
But Map<Object, Object> isn't a Map<? extends String, ? extends String>... it can contain non-string keys and values.
This would work:
Map<Object, Object> map = new HashMap<Object, Object>();
... but it wouldn't be as useful to you.
Fundamentally, Properties should never have been made a subclass of HashTable... that's the problem. Since v1, it's always been able to store non-String keys and values, despite that being against the intention. If composition had been used instead, the API could have only worked with string keys/values, and all would have been well.
You may want something like this:
Map<String, String> map = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
map.put(key, properties.getProperty(key));
}
I would use following Guava API:
com.google.common.collect.Maps#fromProperties
Properties properties = new Properties();
Map<String, String> map = Maps.fromProperties(properties);
If you know that your Properties object only contains <String, String> entries, you can resort to a raw type:
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>((Map) properties);
The problem is that Properties implements Map<Object, Object>, whereas the HashMap constructor expects a Map<? extends String, ? extends String>.
This answer explains this (quite counter-intuitive) decision. In short: before Java 5, Properties implemented Map (as there were no generics back then). This meant that you could put any Object in a Properties object. This is still in the documenation:
Because Properties inherits from Hashtable, the put and putAll methods
can be applied to a Properties object. Their use is strongly
discouraged as they allow the caller to insert entries whose keys or
values are not Strings. The setProperty method should be used instead.
To maintain compatibility with this, the designers had no other choice but to make it inherit Map<Object, Object> in Java 5. It's an unfortunate result of the strive for full backwards compatibility which makes new code unnecessarily convoluted.
If you only ever use string properties in your Properties object, you should be able to get away with an unchecked cast in your constructor:
Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);
or without any copies:
Map<String, String> map = (Map<String, String>) properties;
this is only because the constructor of HashMap requires an arg of Map generic type and Properties implements Map.
This will work, though with a warning
Properties properties = new Properties();
Map<String, String> map = new HashMap(properties);
You can use this:
Map<String, String> map = new HashMap<>();
props.forEach((key, value) -> map.put(key.toString(), value.toString()));
First thing,
Properties class is based on Hashtable and not Hashmap. Properties class basically extends Hashtable
There is no such constructor in HashMap class which takes a properties object and return you a hashmap object. So what you are doing is NOT correct. You should be able to cast the object of properties to hashtable reference.
i use this:
for (Map.Entry<Object, Object> entry:properties.entrySet()) {
map.put((String) entry.getKey(), (String) entry.getValue());
}
When I see Spring framework source code,I find this way
Properties props = getPropertiesFromSomeWhere();
// change properties to map
Map<String,String> map = new HashMap(props)

Categories