HashMap return method - java

I have a method in a class, which initialize a HashMap and put some keys and values inside it, then the method returns the HashMap. How can I retrieve the returned HashMap?
public Map<String, String> getSensorValue(String sensorName) {
registerSensor(sensorName);
sensorValues.put("x","25");
sensorValues.put("y","26");
sensorValues.put("z","27");
return sensorValues;
}
And here I call this method from another class:
public static HashMap<String, String> sensValues = new HashMap<String, String>();
AllSensors sensVal = new AllSensors();
sensValues.putAll(sensVal.getSensorValue("orientation"));
String something = sensValues.get("x");
But it does not work in this way
sensValues.putAll(sensVal.getSensorValue("orientation"));
Makes my android application crash.
The point is to retrive returned HashMap somehow.

You shouldn't have to copy the map. Just try using the returned reference:
Map<String, String> map = sensVal.getSensorValue("...");

Your method needs to return a Map<String,String>. In the code you have posted, the Map sensorValues is never initialized.
public Map<String, String> getSensorValue(String sensorName) {
Map<String,String> sensorValues = new HashMap<String,String>();
registerSensor(sensorName);
sensorValues.put("x","25");
sensorValues.put("y","26");
sensorValues.put("z","27");
return sensorValues;
}

Almost as Rich said in his answer, but your method returns a Map which cannot be cast to a HashMap. Try this
Map<String, String> map = sensVal.getSensorValue("...");
Or alternatively change your getSensorValue method so that it returns a HashMap

HashMap sensValues = new HashMap();
Set mapSet = (Set) sensValues.entrySet();
Iterator mapIterator = mapSet.iterator();
while (mapIterator.hasNext()) {
Map.Entry mapEntry = (Map.Entry) mapIterator.next();
String keyValue = (String) mapEntry.getKey();
String value = (String) mapEntry.getValue();
System.out.println("Key : " + keyValue + "= Value : " + value);
}

Also you can try pass by reference aproach,
void main(){
public static HashMap<String, String> sensValues = new HashMap<String, String>();
AllSensors sensVal = new AllSensors();
sensVal.setSensorValue(sensValues ,"orientation");
String something = sensValues.get("x");
}
public void setSensorValue(Map<String, String> sensorValues, String sensorName) {
registerSensor(sensorName);
sensorValues.put("x","25");
sensorValues.put("y","26");
sensorValues.put("z","27");
}

Related

HashMap cannot be cast

I get the following error from the source below. Can anybody help?
java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.TreeMap
I think the problem is in the line:
TreeMap functionResources = (TreeMap) ((Map)
AbstractParameterManager.getResource(resourceId)).get(function);
public abstract class AbstractParameterManager implements ParameterManager {
protected static final Map resourceLocations =
ResourceLocator.locateResources();
protected static final Map resources = new TreeMap();
protected final Map overrides = new TreeMap();
protected static Object getResource(String resourceId) {
Map resourceMap = (Map) resources.get(resourceId);
if (resourceMap == null) {
resourceMap = new TreeMap();
resources.put(resourceId, resourceMap);
}
return resourceMap;
}
protected static Map getResource(String resourceId, String function) {
TreeMap functionResources = (TreeMap) ((Map)
AbstractParameterManager.getResource(resourceId)).get(function);
if (functionResources == null) {
functionResources = new TreeMap();
((Map)
AbstractParameterManager.getResource(resourceId)).put(function,
functionResources);
}
return functionResources;
}
You are not allowed to cast a TreeMap to a HashMap.
You should follow a general guideline in which you first check whether the reference variable is of specific type, and only then perform cast.
Generally speaking, we do a cast from a supertype in the hierarchy to a sub-type to use specific methods provided by sub-type.
So here in this case you can cast TreeMap to a Map, or a HashMap to a Map, but the cast from TreeMap to HashMap or vice versa is not valid.
Instead of trying to typecast the Map as a TreeMap, you can just pass the map as a parameter when instantiating the TreeMap.
e.g.:
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("a", "a");
hashMap.put("c", "c");
hashMap.put("b", "b");
Map<String, String> treeMap = new TreeMap<>(hashMap);
treeMap.forEach((k, v) -> {
System.out.println(k + " | " + v);
});
}
output:
a = a
b = b
c = c
In your case, you'd have to replace the following line:
TreeMap functionResources = (TreeMap)((Map)AbstractParameterManager.getResource(resourceId)).get(function);
by
Map functionResources = new TreeMap((Map)AbstractParameterManager.getResource(resourceId)).get(function);
Now that the issue has been answered, there's a few more issues with your code. Your method getResource always return a map, and even if it doesn't, you'd have another error when you typecast AbstractParameterManager.getResource(resourceId) as a map. I strongly suggest that you change the return type of getResource to Map.
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("a", "a");
hashMap.put("c", "c");
hashMap.put("b", "b");
Map<String, String> treeMap = new TreeMap<>(hashMap);
treeMap.forEach((k, v) -> {
System.out.println(k + " | " + v);
});
}
#TwiN Error in initialization of the map

How to get specific values from an ArrayList of HashMaps

I have created an ArrayList of HashMaps and I know how to get all keys and values of all HashMaps in the list, but then I decided to make it complicated and iterate through the ArrayList and get only specific HashMap values(based on keys). I have no idea how to do that.
How can I modify printArrayList method to get only idand sku values from all hashmaps?
Right now I have the following example:
public class HashmapArraylist {
public static void main(String[] args) throws Exception {
Map<String, Object> map1 = new HashMap<>();
map1.put("id", 1);
map1.put("sku", "test1");
map1.put("quantity", 1);
Map<String, Object> map2 = new HashMap<>();
map2.put("id", 2);
map2.put("sku", "test2");
map2.put("quantity", 2);
Map<String, Object> map3 = new HashMap<>();
map3.put("id", 3);
map3.put("sku", "test3");
map3.put("quantity", 3);
ArrayList<Map<String, Object>> arrayList = new ArrayList<>();
arrayList.add(map1);
arrayList.add(map2);
arrayList.add(map3);
printArrayList(arrayList);
}
public static void printArrayList(ArrayList<Map<String, Object>> arrayList) {
for (Map<String, Object> entry : arrayList) {
for (String key : entry.keySet()) {
String value = entry.get(key).toString();
System.out.println(key + " : " + value);
}
System.out.println("-----------");
}
}
}
Your iterator for the arrayList is correct. To retrieve a value from a map, simply provide the key into the 'get' function of the entry. Since your map has a "String" key to an "Object" value, you can use "toString()" on it to get the string from the Object returned from your key.
public static void printArrayList(ArrayList<Map<String, Object>> arrayList) {
for (Map<String, Object> entry : arrayList) {
String myID = entry.get("id").toString();
String mySKU = entry.get("sku").toString();
System.out.print("id:" + myID + " sku: " + mySKU);
System.out.println("-------------------");
}
}
user681574 seems to have already answered your problem, but I will just add one Java8 example code to do the same thing as you need, using streams
public static void printArrayList(ArrayList<Map<String, Object>> arrayList) {
arrayList.stream() //stream out of arraylist
.forEach(map -> map.entrySet().stream() //iterate through each map in the list, create stream out of maps' entryset
.filter(entry -> entry.getKey().equals("id") || entry.getKey().equals("sku")) //filter out only entries that we need (where key is "id" or "sku")
.forEach(idOrSku -> System.out.println(idOrSku.getKey() + ":" + idOrSku.getValue()))); //Iterate through the id/sku entries and print them out just as we want to
}

Java: implementing Treemap methods on map.entry, possible?

My assignment is to write code that swaps the keys for the values of a map (with non 1:1) ratio, and I thought to create a TreeMap. So far I have:
public static Map<String, Set<String>> reverseMapping(Map<String, String> mapping) {
TreeMap <String, String> temp = (TreeMap<String, String>) mapping;
while (temp.pollFirstEntry() !=null ){
Map.Entry<String, String> iter=temp.pollFirstEntry();
String newKey = iter.get(iter.firstKey());
}
but it's saying that first.Key() is undefined for map.entry and suggests I cast iter. but that just makes things worse.
How can I achieve my goal of breaking the map entry down into its keys and values in a new set and string, respectively? Is this possible using the starting point I have, or at all?
As per your comments, what you want to know is how to iterate over each entries of a map.
Let me explain you how with a simple snippet :
for(Map.Entry<String, String> entry : temp.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
}
I'm pretty sure you can solve your issue now.
This will give you the reverse of a map.
import java.util.*;
public class HelloWorld{
public static void main(String []args){
System.out.println("Hello World");
TreeMap<String, String> tm1 =new TreeMap<String, String>();
tm1.put("Hello" , "Me");
tm1.put("Bye", "Jim");
TreeMap<String , String > reverse = reverse(tm1);
System.out.println(reverse);
}
public static TreeMap<String , String > reverse(TreeMap<String, String> tm1){
TreeMap<String , String > reverse =new TreeMap<String, String>();
for(String s : tm1.keySet())
{
String v= tm1.get(s);
reverse.put(v,s);
}
return reverse;
}
}

Java: Sorting a Map, Map<Long,Map<String, Data>> based on the inner map

I am new to java and is still in the learning phase.
I have a structure
Map<Long, Map<String, Data>> mapData
Data has 2 fields time and distance
and the Map has a time which is a Long field and map with Identifier and Data
the structure looks like this
{190001919 = {[1= [data1], 2=[data2], 3=[data3]},
190001920={[1=[data4], 2=[data5], 3=[data6]},
1900019121= {[1=[data7], 2=[data8], 3=[data9]}}
and then convert it into a map - Map<String,List<Data>> mpData with
idenifier as key and values as the values where there the identifier was the same.
like
{1= [data1,data4,data7], 2= [data2,data5,data8],3= [data3,data6,data9]}
Could some one please help me?
Update:
With the below code, I get
{1= [data7,data7,data7], 2= [data8,data8,data8],3= [data9,data9,data9]}
instead of
{1= [data1,data4,data7], 2= [data2,data5,data8],3= [data3,data6,data9]}
Code:
public static Map<Long, Map<String, Data>> listData;
public static Map<String, List<Data>> mapData;
public convertMapData(Map<Long, Map<String, Data>> array) {
listData = new HashMap();
listData = array;
mapData = new HashMap<>();
Iterator it = listData.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Long, Map<String, Data>> pairs = (Map.Entry) it
.next();
Long keyValue = pairs.getKey();
Map inter = pairs.getValue();
Iterator it2 = inter.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry<String, Data> pairs_2 = (Map.Entry) it2
.next();
String identifierK = pairs_2.getKey();
Data resultV = pairs_2.getValue();
if (!(mapData.containsKey(identifierK))) {
mapData.put(identifierK, new ArrayList<Data>());
}
mapData.get(identifierK).add(resultV);
}
}
}
Define Map<String,List<Data>> listData = new HashMap<String, List<Data>>();
Iterate over mapData's values (seems you don't use the keys of that map).
For every value of mapData, which again is a map, iterate over the entrySet, which gives you key (a String, lets call it K) and value (a Data object, lets call it V) of every entry.
Check if your listData already has a key like K (using containsKey()) and if not, add one, using listData.put(K, new ArrayList<Data>())
add V to the list that's stored for the key: listData.get(K).add(V)
That's all. As Rohit Jain commented, you'll not need a list around the listData map.
Try this:
public Map<String, List<Data>> convert(Map<Long, Map<String, Data>> array) {
Map<String, List<Data>> result = new HashMap<String, List<Data>>();
for (Map<String, Data> inter : array.values()) {
for (Map.Entry<String, Data> entry : inter.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
if (!result.containsKey(k)) {
result.put(k, new ArrayList<Data>());
}
result.get(k).add(v);
}
}
return result;
}

How to change HashMap<K, V> value type from Object to String?

What is the easiest/best way to convert
Map<String, Object>
to
HashMap<String, String>
The API I am using has methods that return a Map but it would be easier if I didn't have to cast the Object to a String each time.
Also, is this even worth doing? Would a HashMap be faster/more efficient than a Map?
I'm assuming I'll have to loop through the original Map and copy the values to the new HashMap.
Thanks in advance!
You can use the constructor as others mentioned:
Map<String, String> newMap = new HashMap(oldMap);
This will only work however if you know that the Objects in question are really Strings.
but there is something I should mention:
Do not confuse interfaces with classes. Map is just an interface; a contract which contains only definitions. A class on the other hand is a concrete implementation of an interface. So it does not make any difference in terms of perfomrance if you use the Map interface or its runtime type (HashMap). It can make a difference however if you swap the implementations (to TreeMap for example).
Edit:
Here is the verbose solution which is liked by EE guys (no casting/rawtypes warning involved):
public class MapConverter {
public Map<String, String> convert(Map<String, Object> oldMap) {
Map<String, String> ret = new HashMap<String, String>();
for (String key : oldMap.keySet()) {
ret.put(key, oldMap.get(key).toString());
}
return ret;
}
}
Using the copy constructor on raw types works:
HashMap<String, String> hashMap = new HashMap(map);
However, the solution is ugly as the type system is ignored.
EDIT1:
When you execute
public static void main(String[] args) throws IllegalArgumentException,
InterruptedException, IOException {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Bla", new Object());
HashMap<String, String> hashMap = new HashMap(map);
System.out.println(hashMap.get("Bla").getClass());
}
you get the class cast exception:
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
It is thrown when "System.out.println(hashMap.get("Bla").getClass());" is executed.
Consequently, the casts are actually delayed.
EDIT2:
You can avoid the copy with
HashMap<String, String> hashMap = (HashMap)map;
However, the problem remains the same as the following code shows:
public static void main(String[] args) throws IllegalArgumentException,
InterruptedException, IOException {
HashMap<String, Object> oldMap = new HashMap<String, Object>();
oldMap.put("Bla", new Object());
HashMap<String, String> hashMap = (HashMap)oldMap;
System.out.println(hashMap.get("Bla").getClass());
}
It behaves like the other example above in EDIT1.
EDIT3:
What about using a lambda?
Map<String, Object> map = new HashMap<String, Object>();
// 1
final Stream<Map.Entry<String, Object>> entries = map.entrySet()
.stream();
final Function<Map.Entry<String, Object>, String> keyMapper = (
Map.Entry<String, Object> entry) -> entry.getKey();
final Function<Map.Entry<String, Object>, String> valueMapper = (
Map.Entry<String, Object> entry) -> {
final Object value = entry.getValue();
if (value instanceof String) {
return (String) value;
} else {
throw new ClassCastException("Value '" + value + "' of key '"
+ entry.getKey() + "' cannot be cast from type "
+ ((value != null) ? value.getClass().getName() : null)
+ " to type " + String.class.getName());
}
};
final BinaryOperator<String> duplicateHandler = (key1, key2) -> {
throw new IllegalStateException(String.format("Duplicate key %s",
key1));
};
final HashMap<String, String> hashMap = entries.collect(Collectors
.toMap(keyMapper, valueMapper, duplicateHandler, HashMap::new));
System.out.println(hashMap);
If map only has string-to-string entries, it will copy them all.
E.g. Insert
map.put("aKey", "aValue");
at comment 1. It will print
{aKey=aValue}
which is fine.
If you have at least one string-to-non-string entry in your map, copying will fail.
E.g. Insert
map.put("aKey", 42);
at comment 1. It will print
Exception in thread "main" java.lang.ClassCastException: Value '42' of key ' aKey' cannot be cast from type java.lang.Integer to type java.lang.String
at ...
which shows the string-to-non-string entry.
I know this solution is not so simple but it is safe.
If you know the types of key and value (like <String, String>), you can just cast the whole map:
Map<String, String> newMap = (HashMap<String, String>)oldMap;
If you need a separate Map instance, you can use the constructor of HashMap like this:
HashMap<String, String> = new HashMap<String, String>((HashMap<String, String>) oldMap);

Categories