Method createBuilderFactory in javax.json needs argument of type Map<String, ?>
Generally, we have map with like Map<String, String>(some other data types in place of String)
But I didn't understand what does ? stands for. And in order to pass argument of type Map<String, ?>, how I should define the map.
Can someone please help me to understand this better?
In Java generics the ? stands for wildcard, which represent any object.
If you create a method that takes Map<String, ?> you are saying that you expect a Map that maps from String keys to any possible object values:
public static void main(String[] args) {
Map<String, Object> map1 = null;
Map<String, String> map2 = null;
test(map1);
test(map2);
}
private static void test(Map<String, ?> settings) {}
I had difficulties when I need to pass Map<String, ?> to my function, which was accepting Map<String, Object>. And this cut it:
Map<String, ?> mapQuestion = ...
mapObject = (Map<String, Object>)mapQuestion;
Related
I have a reference:
public final static LinkedHashMap<String, Function<OrderBean, String>> DELEGATES;
Which I initialize like:
static {
LinkedHashMap<String, Function<OrderBean, String>> tmp = new LinkedHashMap<>();
tmp.put(OrderCols.FIELD1, OrderBean::getFIELD1);
tmp.put(OrderCols.FIELD2, OrderBean::getFIELD2);
...
DELEGATES = Collections.unmodifiableMap(tmp);
}
On the last line of the static block (the assignment to DELEGATES), I get this compiler error:
Error:(64, 48) java: incompatible types: no instance(s) of type variable(s) K,V exist so that java.util.Map conforms to java.util.LinkedHashMap>
Am I messing something up? Or do unmodifiable views don't like Function types?
No, your issue is that instead of
public final static LinkedHashMap<String, Function<OrderBean, String>> DELEGATES;
you should have
public final static Map<String, Function<OrderBean, String>> DELEGATES;
...because unmodifiableMap returns a bare Map implementation. (The backing data structure will still be a LinkedHashMap, though.)
I am using an interface method that returns the map with these key, values.
public interface IParse<T> {
Map<String, T> parse(); //T is an enum type
}
Now in the implementation classes, I use the function parse with
public class TestClass1 implements IParse
{
public Map<String, EnumType1> parse()
{
Map<String, EnumType1> map1 = new HashMap<>();
// Logic to fill the map
return map1;
}
}
public class TestClass2 implements IParse
{
public Map<String, EnumType2> parse()
{
Map<String, EnumType2> map2 = new HashMap<>();
// Logic to fill the map
return map2;
}
}
and return the map containing appropriate enum type. But eclipse seems does not like it. One of the help options shows "Infer Generic Type Arguments".
Now in the above case, how do I use properly return the map without any type casting. Is there any other way I can use the interface method with a return value a map containing values as enum class types. Please give me an example on how to do this.
Please let me know if any further details are required.
The following code doesn't compile
import com.google.common.collect.LinkedHashMultimap;
public class Test {
public static void main(String[] args) {
LinkedHashMultimap<String, String> p = new LinkedHashMultimap<String, String>();
}
}
the error is: The constructor LinkedHashMultimap() is not visible
I have imported the google Java libraries, they are in the build path
and
LinkedHashMultimap<String, String> p;
alone doesn't cause compile error... weird
Use the static create method to get a new instance of LinkedHashMultimap.
LinkedHashMultimap<String, String> p = LinkedHashMultimap.create();
LinkedHashMultimap has no public constructors and the way to get an instance is by using the factory method create. The reason for this is the loophole in Java Generics due to which type inference works only for methods and not for constructors. This means that instead of for example
LinkedHashMultimap<String, Map<String, List<String>>> =
new LinkedHashMultimap<String, Map<String, List<String>>>();
you can write
LinkedHashMultimap<String, Map<String, List<String>>> =
LinkedHashMultimap.create();
With Java 7 the pressure has subsided due to the "diamond operator".
I have created a webservice which takes a HashMap as parameter.
I generated the stubs/skeletion using XMLBeans and I am trying to set the values in the parameter and pass it to the webservice.
The issue is:
I have the HashMap or List and API is expecting it to be XMLObject is there any conversion utility which can be useful to convert my value to XMLObject?
not sure about conversion, but I have successfully sent HashMap via webservice by wrapping the HashMap in an object like so:
class MapObject {
HashMap<String, String> myMap;
public MapObject(){}
public HashMap<String, String> getMap() {
return myMap;
}
public void setMyMap(HashMap<String, String> myMap) {
this.myMap = myMap;
}
}
Then just make your web service parameter type MapObject.
I have a method with the following signature
public static ActionDefinition reverse(String action, Map<String, Object> args)
And I have method that returns the following:
public static Map<String, String> toMap(String value)
Is there some way I can cast the output of toMap to be used in reverse, something like:
ActionDefinition ad = reverse("Action.method", toMap("param1=value1,param2=value2"));
I'd need to do something like
(Map<String, Object>) toMap("param1=value1,param2=value2");
but I couldn't fin the way to do it
I also tried with the following method
public static Map<String, String> toMap(String value) {
Map<String, Object> source = toMap(value);
Map<String, String> map = new LinkedHashMap<String, String>();
for(Map.Entry<String, Object> entry: source.entrySet()) {
map.put(entry.getKey(), (String) entry.getValue());
}
return map;
}
but I guess that due to type erasure, I get that the method is duplicated...
any idea?
--
edit
I forgot to state that I can't change reverse method, as many have suggested so far...
if you can change the method you wanna call to
public static ActionDefinition reverse(String action, Map<String, ? extends Object> args)
Change the method signature of reverse to use generics
public static ActionDefinition reverse(String action, Map<String, ? extends Object> args)
Cast it to simple (Map), but beware you are cheating.
You can always cast it to Map because it is one, and you can always feed a raw type into a method because of backwards compatibility, so casting a parametrized type to a raw one is always a way to convert it to any other parameters. But you should only do that when you know that it won't introduce a bug and if you have no sensible alternative.