I know it's a noob question but i cant find anything online.I have this HashMap :
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) children.item(i);
map.put("title", ParseXMLmethods.getValue(e, "title"));
map.put("pubDate", ParseXMLmethods.getValue(e, "pubDate"));
map.put("link", ParseXMLmethods.getValue(e, "link"));
map.put("description",ParseXMLmethods.getValue(e, "description"));
localist.add(map);
I am getting an error on localist saying:"localist cannot be resolved". i know i have to declare localist but i don't know which variable type to use . Any help would be really appreciated.
First of all, declare your Map variables as the interface Map and initialize them as the implementation, e.g.
Map<String, String> map = new HashMap<String, String>();
you can also use the diamond operator <> to infer the template types, e.g.
HashMap<String, String> map = new HashMap<>();
While the above are not necessary, they are good practices.
Now, to declare your localist, you can do something like:
List<Map<String, String>> localist = new ArrayList<>();
which is a list of maps that map a string to a string.
If you're trying to add the map to a list, then you would use a List<Map> implementation, via ArrayList or LinkedList primarily. However why you would be keeping a list of Maps would be beyond me, I would recommend a class for this if you're storing multiple maps.
depending on how specific you want to be with your type, you could use ArrayList<HashMap<String, String>> localist = new ArrayList<HashMap<String, String>>();
As stated by the other answer, I would take some time to plan your Classes in your system first. Often if you can't find an answer online, it could suggest that your approach is not best practice or design when it comes to writing extensible and modular code.
You should always consider using abstract or interface types instead of concrete implementations for a start:
AbstractList<Map<String,String>>
Related
So I'm working on a plugin for Atlassian Confluence and in my controller for the configuration page I have a HashMap of Type HashMap<Integer, String> that I fill with values from a HTML form. Now after submitting the form, I try to read a value from that HashMap with .get(key) and safe that to a String. I get this typecasting error: java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String. So I looked at the values with a debugger and sure enough my HashMap contains strings wrapped in arrays of length 1 instead of plain simple strings: even tough my HashMap clearly is defined with types Integer->String and the assignment to String works without any explicit typecasting. This is really confusing me. I guess it has to do with the Atlassian stuff automagically deserializing POST-Values; in the past this has already cost me quite a lot of headaches, as there is no proper documentation and the magical background conversion has quite a lot of quirks. What really confuses me tough is the fact that the HashMap can suddenly store values of a different type than defined, I wouldn't have thought it possible with Java putting such a focus on type safety. Is there some reflection foo that can do this, that I'm unaware of? Or am I misunderstanding the nature of HashMaps? Anybody ever experienced something similar? I'm not that experienced at coding in Java.
In case you are creating hashmap as HashMap<Integer, String>() but storing it as HashMap it is indeed possible to store there other types.
For example:
HashMap map = new HashMap<Integer, String>();
map.put(1, new String[]{"1", "2"});
System.out.println(map.get(1));
This code executes without any errors.
So I think what happens is that in you are storing it just as a HashMap reference which is treated as HashMap<Object, Object> and as there is no runtime information about actual generic types you are able to add objects of other types to this collection.
But if you have another reference to the same map with HashMap<Integer, String> then when you call, for example, get(), it would fail with exception you described:
HashMap map = new HashMap<Integer, String>();
map.put(1, new String[]{"1", "2"});
System.out.println(map.get(1));
System.out.println("got here");
HashMap<Integer, String> otherRef = (HashMap<Integer, String>) map;
System.out.println(otherRef.get(1)); //<-ClassCastException exception here
I'm trying Kotlin and I've encountered a small problem that I can't resolve.
When I have the following construction I can put elements into the map:
val map = HashMap<String, String>()
map["asd"] = "s"
map.put("34", "354")
However when I create a map with the Map interface I can only read them, what I'm doing wrong ?
val map: Map<String, String> = HashMap<String, String>();
map.put("24", "34") //error
map["23"] = "23" //error
Or maybe I'm confusing something about interfaces in Kotlin ?
In the first example map gets the type of HashMap,
in the second example you cast it to the Interface Map.
Map is a readonly map, there is no put/set, see here
In order to be able to edit the map, you should use MutableMap
When working with kotlin collections, one important consideration is that, kotlin categorizes its collections as mutable and immutable. this is in contrast to java, where no such categorization exists.
In kotlin for most collections you have a base interface which only supports read-only methods. In your case Map<K,V is an example of that, from the docs
Methods in this interface support only read-only access to the map;
read-write access is supported through the MutableMap interface.
this is the reason for error when you try to modify the map after val map: Map<String, String> = HashMap<String, String>();, even though the actual object is of type HashMap<String,String>, but the map reference is of type Map<String,String>, which will only provide read only operation.
Now if you use a class which implements MutableMap<K,V> then you can put values in map as well. this is the case with val map = HashMap<String, String>(), since here type of map is HashMap<K,V>, which extends MutableMap<K,V> and hence is mutable.
I use this common initialization format when I anticipate changing the implementation of the List interface at a later time:
List<Foo> foos = new ArrayList<Foos>();
In an effort to gain the same utility for the values within a Map, I attempted the following but my compiler whines about List<> and ArrayList<> being incompatible types.
Map<String, List<Foo>> fooMap = new HashMap<String, ArrayList<Foo>>;
I've been unable to find an explanation for why I cannot initialize the map in this manner and I'd like to understand the reasoning.
And, sure, this works...
Map<String, List<Foo>> foosMap = new HashMap<String, List<Foo>>;
// ... populate map
ArrayList<Foo> foosAryLst = (ArrayList)foosMap.get("key1");
... but I'm a curious castaphobe. I'd rather fix compile-time errors than runtime errors, things like this aggravate my OCD and the smell of casting conjures an odor similar to the urinal trough after free deep-fried asparagus night at the stadium.
My questions come down to:
Why can I not code my map values to an interface.
Is there a workaround that doesn't require casting?
Any input will be appreciated, thanks!
Sure, there's a workaround that doesn't require casting: don't cast; write
List<Foo> foosLst = foosMap.get("key1");
...and code to the interface with the List as well as the Map.
The root issue, though, is that a Map<String, ArrayList<Foo>> isn't substitutable wherever you'd use Map<String, List<Foo>>. In particular,
Map<String, List<Foo>> map = new HashMap<>();
map.put("foo", new LinkedList<Foo>());
works, but not if map is a Map<String, ArrayList<Foo>>. So one isn't a drop-in substitute for the other.
The declaration that you proposed
Map<String, List<Foos>> fooMap = new HashMap<String, ArrayList<Foos>>();
simply does not make sense: The variable fooMap has the type Map<String, List<Foos>>. This means:
every value that you obtain from this map is a List<Foos>
you may put every value into this list that is (of a subtype of) List<Foos>
If you wanted a map that has ArrayLists as its values, then you would declare it as
Map<String, ArrayList<Foos>> fooMap = new HashMap<String, ArrayList<Foos>>();
If you don't care about the list type, then you can say
Map<String, List<Foos>> fooMap = new HashMap<String, List<Foos>>();
But there's no sensible meaning of mixing the two. Even if you could write what you proposed, then you could still not obtain an ArrayList from this map, because this is simply not the type that fooMap was declared with.
In most cases,
Map<String, List<Foos>> fooMap = new HashMap<String, List<Foos>>();
should be appropriate. Depending on the use case, one could possibly go further by saying
Map<String, List<? extends Foos>> fooMap = new HashMap<String, List<? extends Foos>>();
This way, you can also put lists into the map that contain sublcasses of Foos, like
List<SpecialFoos> specialFoos = ...
fooMap.put("special", specialFoos);
But of course, it's up to you to decide whether this is necessary or not.
The core of the problem is that the compiler cannot keep track of what fooMap may have been assigned to at any particular point in the execution of your code, so there is no way for the compiler to know that
fooMap.put("abc", new ArrayList<Foo>())
should be legal, but that
fooMap.put("abc", new LinkedList<Foo>())
should not be.
All that the compiler knows about the typing of fooMap is its declared type Map<String, List<Foo>>. So, it enforces that whatever object to which you assign fooMap must be able to support all of the operations which a generic Map<String, List<Foo>> is capable of executing. The second line of code above is clearly legal for a Map<String, List<Foo>>, but not legal for a Map<String, ArrayList<Foo>>, so the compiler forbids you from assigning fooMap to a Map<String, ArrayList<Foo>>.
Like String s="sample" in java.How to declare and assign values to a hashMap in one step. Also is it possible to assign more set of values at a time using put function in hashMap.
Yes, it is possible. you can use the below code
HashMap<String,String> instruments = new HashMap<String, String>() {
{
put("test","test");
put("test1","test1");
}
};
Use a library like Google Guava which has lots of utilities to instantiate HashMaps. It is also possible doing anonymous inheritance like this:
Map<String, Object> map = new HashMap<String, Object>() {{
put("Test", "Test1");
put("Test", "Test1");
}};
But I wouldn't recommend it.
such constructs do not exist in good ol' java.
On one hand, you can use property files format for that. You can save your map as a something-separated key-value pairs in a string or a file, and read them in a loop filling your map with each pair.
on the other hand, if you really need that + possible type-checking, you can look at modern dynamic JVM languages, like Groovy or Scala.
there you can use the code as it is:
def map = [ a:1, b:23, c:"aasdasd" ]
Map<String, ArrayList<Pair<String, Integer>>> k = new Map<String, ArrayList<Pair<String, Integer>>>();
This line is in my code. I'd like to instantiate a Map that contains a String then an ArrayList of Pairs of Strings and Integers.
Pair is a class that I wrote that is in my package.
I get "Cannot Instantiate the type Map>>();
Why not? Seems reasonable to me...
The built-in Map is an interface, which cannot be instantiated. You can choose between lots of implementing concrete classes on the right side of your assignment, such as:
ConcurrentHashMap
HashMap
LinkedHashMap
TreeMap
and many others. The Javadocs for Map lists many direct concrete implementations.
Interfaces cant be intantiated
You need to use some concrete class implementing the interface
Try something like this
Map<String, ArrayList<Pair<String, Integer>>> k = new HashMap<String, ArrayList<Pair<String, Integer>>>();