Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why HashMap Values are not cast in List?

I'm putting values into the hashmap which is of the form,

Map<Long, Double> highLowValueMap=new HashMap<Long, Double>(); highLowValueMap.put(1l, 10.0); highLowValueMap.put(2l, 20.0); 

I want to create a list by using values() method of map.

List<Double> valuesToMatch=new ArrayList<>(); valuesToMatch=(List<Double>) highLowValueMap.values(); 

or

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values(); 

However, it throws an exception:

Exception in thread "main" java.lang.ClassCastException:
java.util.HashMap$Values cannot be cast to java.util.List

But it allows me to pass it in to the creation of a list:

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values()); 
like image 962
bNd Avatar asked Mar 20 '13 11:03

bNd


People also ask

Can a HashMap value be a list?

Idea behind associating Multiple values with same key is to store another Collection as Value in the HashMap. This can be a List or Set or any other Map too.

Can the value of a HashMap be an ArrayList?

A HashMap contains key-value pairs, there are three ways to convert a HashMap to an ArrayList: Converting the HashMap keys into an ArrayList. Converting the HashMap values into an ArrayList.

Are Hashmaps lists?

The difference between ArrayList and HashMap is that ArrayList is an index-based data-structure supported by array, while the HashMap is a mapped data structure, which works on hashing to retrieve stored values. Although both are used to store objects, they are different in their implementation, function, and usage.


2 Answers

TL;DR

List<V> al = new ArrayList<V>(hashMapVar.values()); 

Explanation

Because HashMap#values() returns a java.util.Collection<V> and you can't cast a Collection into an ArrayList, thus you get ClassCastException.

I'd suggest using ArrayList(Collection<? extends V>) constructor. This constructor accepts an object which implements Collection<? extends V> as an argument. You won't get ClassCastException when you pass the result of HashMap.values() like this:

List<V> al = new ArrayList<V>(hashMapVar.values()); 

Going further into the Java API source code

HashMap#values(): Check the return type in the source, and ask yourself, can a java.util.Collection be casted into java.util.ArrayList? No

public Collection<V> values() {     Collection<V> vs = values;     return (vs != null ? vs : (values = new Values())); } 

ArrayList(Collection): Check the argument type in the source. Can a method which argument is a super type accepts sub type? Yes

public ArrayList(Collection<? extends E> c) {     elementData = c.toArray();     size = elementData.length;     // c.toArray might (incorrectly) not return Object[] (see 6260652)     if (elementData.getClass() != Object[].class)         elementData = Arrays.copyOf(elementData, size, Object[].class); } 
like image 88
PermGenError Avatar answered Sep 18 '22 11:09

PermGenError


The answer can be found by reading the JavaDoc

The values() method returns a Collection

So

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values(); 

Should be

Collection<Double> valuesToMatch= highLowValueMap.values(); 

You can still iterate over this collection as you would a list.

http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html#values%28%29


This works:

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values() ); 

Because ArrayList has a constructor that accepts a collection.

like image 43
cowls Avatar answered Sep 19 '22 11:09

cowls