Converting ConcurrentHashMap to HashMap - java

Is it possible to convert ConcurrentHashMap to HashMap in java ?
This is my sample program where i was converting from ConcurrentHashMap to HashMap but i was getting the following exception:
Exception in thread "main" java.lang.ClassCastException:
java.util.concurrent.ConcurrentHashMap cannot be cast to java.util.HashMap
at com.Hi.main(Hi.java:18)
My code:
package com;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Hi {
public static void main(String args[]) {
Map<String, String> conpage = new ConcurrentHashMap<String, String>();
conpage.put("1", "A");
conpage.put("2", "B");
conpage.put("3", "C");
HashMap hm = (HashMap) conpage;
System.out.println(hm.get("1"));
}
}

Map<String, String> hashMap = new HashMap<String, String>(conpage);
A ConcurrentMap (like ConcurrentHashMap) has no relationship with any AbstractMap, such has HashMap, so the solution is to create a new HashMap adding all values from ConcurrentHashMap during object creation.
Hope this helps.

A ConcurrentHashMap is not a HashMap , so you cannot perform this cast. Treat them as Map regardless of implementation.
Nevertheless , you can use Map#putAll() .
Suggested Reading:
Java - HashMap vs Map objects
What does it mean to “program to an interface”?

Use putAll() method istead of type casting like this:
HashMap hm=new HashMap<String, String>();
hm.putAll(conpage);

ConcurrentHashMap and HashMap are siblings and not Parent-Child related. Hence the cast fails.

To be more explicit in the explanation of the previous comments: consider you have three classes :
class Position {
}
class One extends Position {
String gold = "the best";
}
class Two extends Position {
String silver = "just wait next year!";
}
You cannot do the following cast (note that a cast is not a conversion: it's only a redeclaration of the type)
void showPosition() {
Position one = new One(); // this is regular since One extends Position
Two two = (Two)one; // this is impossible because one is not a two
}
If ever this cast was possible, how would you like the compiler to handle the following promblem? : there is no field called silver in one: so calling
((Two)one).silver
is impossible: returning null would be unsafe, since you wouldn't understand what's happening : since you know that the field 'silver' is initialized to the value "just wait next year!"
Java being a safe language, it doesn't allow this type of errors (actually it's a help from Java that it throws the exception since you think the type is something else that is it is).
The behvior you expect is rather a behavior proper to scripts.

A ConcurrentHashMap is still a Map. So you can create a new TreeMap like this:
ConcurrentHashMap myMap;
...
TreeMap myTreeMap = new TreeMap( myMap );

You can do so in the following way -
HashMap<String, String> map = new HashMap<String, String>(conpage);
JavaDoc.
Typically each concrete type in the Java Collection API (like HashMap, ArrayList etc.) has a constructor which takes a reference of its parent (like Map, List) and constructs a new object from it.
About the exception you are getting, it's because ConcurrentHashMap is not a subtype/supertype of HashMap, thus you are getting a ClassCastException. However, this would have worked fine -
Map<String, String> hm = (Map<String, String> ) conpage;

Actually There is no inheritance relation between HashMap and ConcurrentHashMap that's why while casting the concurrenthashmap object to hashmap its giving the ClassCastException.

Related

JAVA: List<List<? extends Object>> vs List<List<Object>> [duplicate]

I'm using Eclipse to help me clean up some code to use Java generics properly. Most of the time it's doing an excellent job of inferring types, but there are some cases where the inferred type has to be as generic as possible: Object. But Eclipse seems to be giving me an option to choose between a type of Object and a type of '?'.
So what's the difference between:
HashMap<String, ?> hash1;
and
HashMap<String, Object> hash2;
An instance of HashMap<String, String> matches Map<String, ?> but not Map<String, Object>. Say you want to write a method that accepts maps from Strings to anything: If you would write
public void foobar(Map<String, Object> ms) {
...
}
you can't supply a HashMap<String, String>. If you write
public void foobar(Map<String, ?> ms) {
...
}
it works!
A thing sometimes misunderstood in Java's generics is that List<String> is not a subtype of List<Object>. (But String[] is in fact a subtype of Object[], that's one of the reasons why generics and arrays don't mix well. (arrays in Java are covariant, generics are not, they are invariant)).
Sample:
If you'd like to write a method that accepts Lists of InputStreams and subtypes of InputStream, you'd write
public void foobar(List<? extends InputStream> ms) {
...
}
By the way: Joshua Bloch's Effective Java is an excellent resource when you'd like to understand the not so simple things in Java. (Your question above is also covered very well in the book.)
Another way to think about this problem is that
HashMap<String, ?> hash1;
is equivalent to
HashMap<String, ? extends Object> hash1;
Couple this knowledge with the "Get and Put Principle" in section (2.4) from Java Generics and Collections:
The Get and Put Principle: use an
extends wildcard when you only get
values out of a structure, use super
wildcard when you only put values into
a structure, and don't use a wildcard
when you both get and put.
and the wild card may start making more sense, hopefully.
It's easy to understand if you remember that Collection<Object> is just a generic collection that contains objects of type Object, but Collection<?> is a super type of all types of collections.
The answers above covariance cover most cases but miss one thing:
"?" is inclusive of "Object" in the class hierarchy. You could say that String is a type of Object and Object is a type of ?. Not everything matches Object, but everything matches ?.
int test1(List<?> l) {
return l.size();
}
int test2(List<Object> l) {
return l.size();
}
List<?> l1 = Lists.newArrayList();
List<Object> l2 = Lists.newArrayList();
test1(l1); // compiles because any list will work
test1(l2); // compiles because any list will work
test2(l1); // fails because a ? might not be an Object
test2(l2); // compiled because Object matches Object
You can't safely put anything into Map<String, ?>, because you don't know what type the values are supposed to be.
You can put any object into a Map<String, Object>, because the value is known to be an Object.
Declaring hash1 as a HashMap<String, ?> dictates that the variable hash1 can hold any HashMap that has a key of String and any type of value.
HashMap<String, ?> map;
map = new HashMap<String, Integer>();
map = new HashMap<String, Object>();
map = new HashMap<String, String>();
All of the above is valid, because the variable map can store any of those hash maps. That variable doesn't care what the Value type is, of the hashmap it holds.
Having a wildcard does not, however, let you put any type of object into your map. as a matter of fact, with the hash map above, you can't put anything into it using the map variable:
map.put("A", new Integer(0));
map.put("B", new Object());
map.put("C", "Some String");
All of the above method calls will result in a compile-time error because Java doesn't know what the Value type of the HashMap inside map is.
You can still get a value out of the hash map. Although you "don't know the value's type," (because you don't know what type of hash map is inside your variable), you can say that everything is a subclass of Object and, so, whatever you get out of the map will be of the type Object:
HashMap<String, Integer> myMap = new HashMap<>();// This variable is used to put things into the map.
myMap.put("ABC", 10);
HashMap<String, ?> map = myMap;
Object output = map.get("ABC");// Valid code; Object is the superclass of everything, (including whatever is stored our hash map).
System.out.println(output);
The above block of code will print 10 to the console.
So, to finish off, use a HashMap with wildcards when you do not care (i.e., it does not matter) what the types of the HashMap are, for example:
public static void printHashMapSize(Map<?, ?> anyMap) {
// This code doesn't care what type of HashMap is inside anyMap.
System.out.println(anyMap.size());
}
Otherwise, specify the types that you need:
public void printAThroughZ(Map<Character, ?> anyCharacterMap) {
for (int i = 'A'; i <= 'Z'; i++)
System.out.println(anyCharacterMap.get((char) i));
}
In the above method, we'd need to know that the Map's key is a Character, otherwise, we wouldn't know what type to use to get values from it. All objects have a toString() method, however, so the map can have any type of object for its values. We can still print the values.

Confused on the difference between ConcurrentHashMap and HashMap behavior in this example

I'm trying to understand how ConcurrentHashMap works. I found an example, but I'm not able to understand it. Here's its code:
Map<String, Object> myData = new HashMap<String, Object>();
myData.put("A", 1);
myData.put("B", 2);
for (String key : myData.keySet()) {
myData.remove(key);
}
This will throw an exception ConcurrentModificationException at runtime.
However, this code using ConcurrentHashMap will work correctly:
Map<String, Object> myData = new ConcurrentHashMap<String, Object>();
myData.put("A", 1);
myData.put("B", 2);
for (String key : myData.keySet()) }
myData.remove(key);
}
Can someone explain to me why ConcurrentHashMap allows to remove keys while the HashMap throws an exception? Thanks
That's just one of the features of ConcurrentHashMap. To quote from the docs:
Similarly, Iterators, Spliterators and Enumerations return elements
reflecting the state of the hash table at some point at or since the
creation of the iterator/enumeration. They do not throw
ConcurrentModificationException.
ConcurrentHashMap does not really do this to support your use case, however. It's done to allow iteration in one thread happen concurrently with modifications made in other threads.
If this is your only reason for using ConcurrentHashMap, then you should probably reconsider, because it is a lot more expensive than HashMap. You are better off just making a copy of the key set before using it like this:
Map<String, Object> myData = new HashMap<String, Object>();
myData.put("A", 1);
myData.put("B", 2);
for(String key: myData.keySet().toArray(new String[0]))
myData.remove(key);

Unbounded wildcards vs Object type parameter in Java [duplicate]

I'm using Eclipse to help me clean up some code to use Java generics properly. Most of the time it's doing an excellent job of inferring types, but there are some cases where the inferred type has to be as generic as possible: Object. But Eclipse seems to be giving me an option to choose between a type of Object and a type of '?'.
So what's the difference between:
HashMap<String, ?> hash1;
and
HashMap<String, Object> hash2;
An instance of HashMap<String, String> matches Map<String, ?> but not Map<String, Object>. Say you want to write a method that accepts maps from Strings to anything: If you would write
public void foobar(Map<String, Object> ms) {
...
}
you can't supply a HashMap<String, String>. If you write
public void foobar(Map<String, ?> ms) {
...
}
it works!
A thing sometimes misunderstood in Java's generics is that List<String> is not a subtype of List<Object>. (But String[] is in fact a subtype of Object[], that's one of the reasons why generics and arrays don't mix well. (arrays in Java are covariant, generics are not, they are invariant)).
Sample:
If you'd like to write a method that accepts Lists of InputStreams and subtypes of InputStream, you'd write
public void foobar(List<? extends InputStream> ms) {
...
}
By the way: Joshua Bloch's Effective Java is an excellent resource when you'd like to understand the not so simple things in Java. (Your question above is also covered very well in the book.)
Another way to think about this problem is that
HashMap<String, ?> hash1;
is equivalent to
HashMap<String, ? extends Object> hash1;
Couple this knowledge with the "Get and Put Principle" in section (2.4) from Java Generics and Collections:
The Get and Put Principle: use an
extends wildcard when you only get
values out of a structure, use super
wildcard when you only put values into
a structure, and don't use a wildcard
when you both get and put.
and the wild card may start making more sense, hopefully.
It's easy to understand if you remember that Collection<Object> is just a generic collection that contains objects of type Object, but Collection<?> is a super type of all types of collections.
The answers above covariance cover most cases but miss one thing:
"?" is inclusive of "Object" in the class hierarchy. You could say that String is a type of Object and Object is a type of ?. Not everything matches Object, but everything matches ?.
int test1(List<?> l) {
return l.size();
}
int test2(List<Object> l) {
return l.size();
}
List<?> l1 = Lists.newArrayList();
List<Object> l2 = Lists.newArrayList();
test1(l1); // compiles because any list will work
test1(l2); // compiles because any list will work
test2(l1); // fails because a ? might not be an Object
test2(l2); // compiled because Object matches Object
You can't safely put anything into Map<String, ?>, because you don't know what type the values are supposed to be.
You can put any object into a Map<String, Object>, because the value is known to be an Object.
Declaring hash1 as a HashMap<String, ?> dictates that the variable hash1 can hold any HashMap that has a key of String and any type of value.
HashMap<String, ?> map;
map = new HashMap<String, Integer>();
map = new HashMap<String, Object>();
map = new HashMap<String, String>();
All of the above is valid, because the variable map can store any of those hash maps. That variable doesn't care what the Value type is, of the hashmap it holds.
Having a wildcard does not, however, let you put any type of object into your map. as a matter of fact, with the hash map above, you can't put anything into it using the map variable:
map.put("A", new Integer(0));
map.put("B", new Object());
map.put("C", "Some String");
All of the above method calls will result in a compile-time error because Java doesn't know what the Value type of the HashMap inside map is.
You can still get a value out of the hash map. Although you "don't know the value's type," (because you don't know what type of hash map is inside your variable), you can say that everything is a subclass of Object and, so, whatever you get out of the map will be of the type Object:
HashMap<String, Integer> myMap = new HashMap<>();// This variable is used to put things into the map.
myMap.put("ABC", 10);
HashMap<String, ?> map = myMap;
Object output = map.get("ABC");// Valid code; Object is the superclass of everything, (including whatever is stored our hash map).
System.out.println(output);
The above block of code will print 10 to the console.
So, to finish off, use a HashMap with wildcards when you do not care (i.e., it does not matter) what the types of the HashMap are, for example:
public static void printHashMapSize(Map<?, ?> anyMap) {
// This code doesn't care what type of HashMap is inside anyMap.
System.out.println(anyMap.size());
}
Otherwise, specify the types that you need:
public void printAThroughZ(Map<Character, ?> anyCharacterMap) {
for (int i = 'A'; i <= 'Z'; i++)
System.out.println(anyCharacterMap.get((char) i));
}
In the above method, we'd need to know that the Map's key is a Character, otherwise, we wouldn't know what type to use to get values from it. All objects have a toString() method, however, so the map can have any type of object for its values. We can still print the values.

How to save enum class in a HashMap?

Let us say we have following enums:
public enum AnimalImages {
TIGER,BEAR,WOLF;
}
public enum CarImages {
BMW,VW,AUDI;
}
Now I want to save these enum classes in a HashMap:
Map<String,Enum<?>> enumMap=new HashMap<String,Enum<?>>();
enumMap.put("AnimalImages",???????);
What I should enter instead of the question marks?
To explicitly answer to your question, you have to put the enum value as this:
Map<String,Enum<?>> enumMap=new HashMap<String,Enum<?>>();
enumMap.put("AnimalImages", AnimalImages.TIGER);
However, if you want to put all the value belonging to an enum, then you could leverage values() method and also change your map to Map<String,Enum<?>[]> so you can use this:
Map<String,Enum<?>[]> enumMap=new HashMap<String,Enum<?>[]>(); // Note Enum<?>[] array
enumMap.put("AnimalImages", AnimalImages.values());
enumMap.put("CarImages", CarImages.values());
Another approach, with a shorten signature can be something like this:
Map<String, Object> enumMap = new HashMap<String,Object>();
enumMap.put("AnimalImages", AnimalImages.values());
enumMap.put("CarImages", CarImages.values());
Another way that bali182 pointed in this comment, you could use:
Map<String, Collection<? extends Enum<?>>> enumMap = new HashMap<>();
enumMap.put("AnimalImages", Arrays.asList(AnimalImages.values()));
enumMap.put("CarImages", Arrays.asList(AnimalImages.values()));
To answer your question:
enumMap.put("AnimalImages", AnimalImages.WOLF);
enumMap.put("Cars", CarImages.AUDI);
But you can also do
Map<String, AnimalImages> enumMap = new HashMap<String, AnimalImages>();
And this way enumMap.get("AnimalImages"), and this way you won't have to type check and cast it.
If the requirement is to create a Map that contains all values of a given enum, I would use a mapping of String keys into EnumSet values:
Map<String, EnumSet<?>> enumMap = new HashMap<String, EnumSet<?>>();
enumMap.put("AnimalImages", EnumSet.allOf(AnimalImages.class));
enumMap.put("CarImages", EnumSet.allOf(CarImages.class));
for (Map.Entry<String, EnumSet<?>> e : enumMap.entrySet()) {
System.out.println(String.format("key: [%s], values: %s",
e.getKey(), e.getValue().toString()));
}
EnumSet is a specialized Set implementation, which is represented internally as a bit vector. Its sole purpose is to provide an efficient and easy way to store enums.

Generics in Java

Is there any shorthand way of defining and using generic definitions without having to keep repeating a particular generic description such that if there is a change I don't have to change all definitions/usages though out the codebase for example is something like this possible:
Typedef myGenDef = < Object1, Object2 >;
HashMap< myGenDef > hm = new HashMap< myGenDef >();
for (Entry< myGenDef > ent : hm..entrySet())
{
.
.
.
}
There's the pseudo-typedef antipattern...
class StringList extends ArrayList<String> { }
Good stuff, drink up! ;-)
As the article notes, this technique has some serious issues, primarily that this "typedef" is actually a separate class and thus cannot be used interchangeably with either the type it extends or other similarly defined types.
In a generic method, you can use a limited form of type inferrence to avoid some repetitions.
Example: if you have the function
<K, V> Map<K, V> getSomething() {
//...
}
you can use:
final Map<String, Object> something = getsomething();
instead of:
final Map<String, Object> something = this.<String, Object>getsomething();
Use Factory Pattern for creation of Generics:
Method Sample:
public Map<String, Integer> createGenMap(){
return new HashMap<String,Integer>();
}
The pseudo-typedef antipattern mentioned by Shog9 would work - though it's not recommended to use an ANTIPATTERN - but it does not address your intentions. The goal of pseudo-typedef is to reduce clutter in declaration and improve readability.
What you want is to be able to replace a group of generics declarations by one single trade. I think you have to stop and think: "in witch ways is it valuable?". I mean, I can't think of a scenario where you would need this. Imagine class A:
class A {
private Map<String, Integer> values = new HashMap<String, Integer>();
}
Imagine now that I want to change the 'values' field to a Map. Why would exist many other fields scattered through the code that needs the same change? As for the operations that uses 'values' a simple refactoring would be enough.
No. Though, groovy, a JVM language, is dynamically typed and would let you write:
def map = new HashMap<complicated generic expression>();

Categories

Resources