Create a list of key value objects - java

I am trying to create a list of key-value pairs. Here is what I have so far:
Map<Integer,String> map = new HashMap<Integer,String>().put(songID, songList.get(i).name);
This gives me the following error:
Type mismatch: cannot convert from String to Map
Also, how would I iterate through these? Thanks!

When you call put on the map of type Map <Integer,String>, you will get the String returned. So when you do this:
new HashMap<Integer,String>().put(songID, songList.get(i).name);
it will return a String
and when you try to assign it to a map
Map<Integer,String> map
compiler throws an error,
Type mismatch: cannot convert from String to Map
Here is the signature of put method form javadocs:
public V put(K key,
V value)
you need to break down the this complex problematic statement:
Map<Integer,String> map = new HashMap<Integer,String>().put(songID, songList.get(i).name);
to something like:
Map<Integer,String> map = new HashMap<Integer,String>();
map.put(songID, songList.get(i).name);

The answer on this thread:
Java HashMap associative multi dimensional array can not create or add elements
has an example of how to do this.

Related

Integer object in a <String, String> hashmap

Create a (String, Object) hashMap and put values of different types.
Serialize the hashmap into a json string and convert back into a hashmap of (String, String)
When I try to get the value of key "key2", it will throw an exception saying "Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String".
Is there a good way to explain this? Does it mean even though I have a (String, String) map, the value in it is not necessary String?
Apologize for any confusion. Let me know if something is not clear.
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", 99);
map.put("key3", new Date());
JsonUtil jsonUtil = new JsonUtil();
String s = jsonUtil.toJson(map);
HashMap<String, String> newMap = jsonUtil.fromJson(s, HashMap.class);
String value = newMap.get("key2");
In map, the value of key "key2" is 99, which is an integer. The exception is possibly being thrown in the second to last line, not the last line. I'm not entirely sure why you are serializing and then immediately deserializing, but if you just want 99 as a String like "99", the way to do this would be:
String value = String.valueOf(map.get("key2"));
The serializing and deserializing would not be necessary in this case.
Better yet, if you just want a Map<String, String> for the whole time, you can do something like this:
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", String.valueOf(99));
map.put(new Date().toString());
When you call fromJson(s, HashMap.class), you're not providing any generic type information to the decoder--all it sees is HashMap, and the implicit return type from that call is HashMap<?,?>. JSON can assume string keys, and the decoder is doing its best to decode objects into their "native" representations, so when you tell the compiler that all of the keys and values are strings, there's a mismatch.
If you specify which JsonUtil is involved, we may be able to provide a more specific approach; otherwise, you could use something like a stream transform to convert every value to v.toString().
String value = newMap.get("key2");
In this line you are getting the value of key2 in hashMap and then assigning it to a String type variable value which is invalid. Because the value of key2 is Integer type, you cannot do this directly. You can put this value in `Integer type variable. as bellow:
int value = newMap.get("key2");
Or if you want a generic solution so that you can assign any type of variable into value then you can declare it as Object type. as bellow:
Object value = newMap.get("key2");

Have complication with Map?

I have this question regarding generics.Can anybody explain me why the options 4 and 6[i know about this option]are correct?
Consider the following code:
import java.util.*;
public class TestClass
{
public static void main(String[] args)
{
// put declaration here
m.put("1", new ArrayList()); //1
m.put(1, new Object()); //2
m.put(1.0, "Hello"); //3
System.out.println(m);
}
}
How can 'm' be declared such that the above code will compile and run without errors?
Map m = new TreeMap();
Map<Object, Object> m = new TreeMap<Object, Object>();
Map<Object, ?> map = new LinkedHashMap<Object, Object>();
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();will work
if lines //2 and //3 are commented out.
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>(); will work if lines //1 and //3 are commented out.
Map m = new HashMap();
For understanding this problem, look at the generic signature of the Map#put method you are using here. It states:
V put(K key, V value)
what means that you can put a key that is assignable to the generic type of the Map's key type K and a value that is assignable to the generic type of the Map's value type V. This must be true for all your key-value pairs you put into the map. From your code, you are putting the following keys into the map:
A String by the literal "1"
An Integer by the boxed int literal 1.
A Double by the boxed double literal 1.0.
The only common super type of these objects is the Object type which is required for K in order to allow all these objects to be used as a key.
For the values you have:
A ArrayList instance.
An Object instance
A String by the literal "Hello"
Again, the only common super type of these objects is the Object type which is required for V in order to allow all these objects to be used as a map value.
As a result, only Map instances with the generic signature Map<Object, Object> are permitted. What implementation of the Map interface you choose is up to you, as long as it is assignable to the variable type of the map, i.e. you can use a LinkedHashMap, a TreeMap or a HashMap since they only differ in the way they store their data. For the generic type of the variables, note that the use of wildcards ? or ? extends ... for your variable will result in you not being able to put values into the map anymore. The tutorial I linked explains why.
As for the types with a non-generic signature you are using, they behave similar to Maps with the generic signature <Object, Object>. Such raw types should however not longer be used after the introduction of Java 5.
With all this information, you can answer your (exam) question yourself.
Number 4 is correct for line 1, because "1" is String which has Object superclass and ? super ArrayList means that you can use ArrayList or any superclass of ArrayList.
Number 6 is correct because you are using untyped(raw) map, so it's similar to:
Map<Object, Object> m = new HashMap<Object, Object>();
To store such values you can use Map, but it's not a really good choice. You shouldn't use untyped collections at all. Think how you can change your design to not use such map.

Does Hashtable get method returns more than one value?

I was converting some code from java to C#, I encountered ArrayList<Integer> values = hashtable.get(h);. Question aroused Does Hashtable get method returns more than one value?
A HashTable returns one value. If that value happens to be an object of type Collection, then that one value will point to several other values.
For example
HashTable<String, ArrayList<Integer>> table = new HashTable<String, ArrayList<Integer>>();
// Populate it with values.
ArrayList<Integer> value = table.get("KEY");
How is this possible?
Simple. Java Generics. This is where you declare a Generic type in a class, and you define it's type at run time. For example:
public class Test<T>
{
private T instance;
public Test(T instance)
{
this.instance = instance;
}
}
That means you can declare this class any way you want.
Test<String> test = new Test<String>();
Test<Integer> test2 = new Test<Integer>();
And the type of instance will be whatever you declare it as.
And because T defaults to type Object, you can even put a Collection in there.
Test<ArrayList<String>> test3 = new Test<ArrayList<String>>();
An ArrayList is one value (an arraylist) by itself
HashTable<something, ArrayList<Integer>> hashtable = new HashTable<something, ArrayList<Integer>>();
So it's gonna map the "something" to an arraylist of integers (i.e. a list)
The return type of get() method is Object. So it is a single Object. But the type can be a List or Any Class in Java.
So the returning Object purely depends on What you inserted before.
If you wold like to have many values for one key use Guava => Multimap
Documentation:
http://guava-libraries.googlecode.com/svn-history/r13/trunk/javadoc/com/google/common/collect/Multimap.html
It does only return a list of values if you put that list in the map (under the certain key).
Map<String, List<Object>> map = new HashMap<>();
... // init map
List<Object> list = map.get(KEY);
but
Map<String, Object> map = new HashMap<>();
map.put(KEY, obj1);
map.put(KEY, obj2);
Object obj = map.get(KEY);

Android parsing an ArrayList

I have the following ArrayList
ArrayList<HashMap<String, String>> list;
HashMap<String, String> map;
with the following values inside:
list[0] = map.put("key_0", value_0);
list[1] = map.put("key_1", value_1);
list[2] = map.put("key_2", value_2);
I would like to parse the list array and get the value of the key at a specific position.
You can get the particular map from the ArrayList> by using get() method. for example,
map = list.get(index);
And to get key of that map, you can do:
String key = map.get("key");
FYI, this is the feasible solution, i dont know why you are using key name like key_0, key_1, key_2...and so on.

Regarding querying Java Map with values as array of string.

I have map of string and array of strings as:
private static Map cacheTimeStamp = new HashMap<String, String[]>();
now how do i get value of this Map, i want to return array of String[] back to the calling function, tried using cacheTimeStamp.get("stringKey") but it returns object and i want to get array of strings out.
Define your map like this:
private static Map<String, String[]> cacheTimeStamp = new HashMap<String, String[]>();
Problem is that you are defining an open map without specifying map's key and value object types. Which is essentially a key of type java.lang.Object and a value of type java.lang.Object.
You didn't define the generics.
Map<String, String[]> cacheTimeStamp = new HashMap<String, String[]>();
It actually did return an array of Strings, but strictly you don't know when you don't include the generics in the definition. That's why the IDE tells you it will be an Object. Make sure you are beware of the fact that an array is an Object.
You actually get an String[].
I see two options:
Cast the return value to an String[]:
String[] myEntry = (String[]) cacheTimeStamp.get("stringKey");
(My preference) Add type arguments to the map:
private static Map cacheTimeStamp = new HashMap();
// ...
String[] myEntry = cacheTimeStamp.get("stringKey");

Categories