I have one Map in java like this:
Map<String index1, Map<String index 2, Object obj>> map = new HashMap<>();
I want to get my Object in the map by using index1 and index2 as lookups.
The easiest way to do this would be to use Guava's Table, if you're willing to use a third party library.
It works like this:
Table<String, String, Object> table = HashBasedTable.create();
table.put(index1, index2, obj);
Object retrievedObject = table.get(index1, index2);
You can add it to your project by following these instructions: How to add Guava to Eclipse project
If you don't want to use Guava, you have a big problem. If you try to insert an element with new first key, you have to make sure the innermap already exists. This means, every time you do put, you have to retrieve the innerMap, see if it exists, and then create it if it does not. You will have to do this every time you call Map.put. Also, you risk throwing a NullPointerException if the inner map doesn't exist when you call get on the inner map.
If you do this, should wrap your Map<String, Map<String, Object> in an outer class to manage these problems, or use Java 8's computeIfAbsent. But the easiest way is to just use Table as above.
If you make your own class to use instead of Table, it would be something like:
public class DoubleMap<R, C, V> {
private final Map<R, Map<C, V>> backingMap;
public DoubleMap() {
this.backingMap = new HashMap<>();
}
public V get(R row, C column) {
Map<C, V> innerMap = backingMap.get(row);
if(map == null) return null;
else return innerMap.get(column);
}
public void put(R row, C column, V value) {
Map<C, V> innerMap = backingMap.get(row);
if(innerMap == null) {
innerMap = new HashMap<C, V>();
backingMap.put(row, innerMap);
}
innerMap.put(column, value);
}
}
You would use this class by doing:
DoubleMap<String, String, Object> map = new DoubleMap();
Note that this answer has a lot less features than the Guava version.
Getting a Value from a Map
If I understand your question, then with an index a and b that might look like (guarding against null with a ternary or Conditional Operator ? :),
Object obj = (map.get("a") == null) ? null : map.get("a").get("b");
Using a Generic Type
And you might be more specific, like
Map<String, Map<String, Something>> map = new HashMap<>();
Something s = (map.get("a") == null) ? null : map.get("a").get("b");
Adding values to the Map
Assuming you want to add your Something value to the map that could be done with something like,
Map<String, Map<String, Something>> map = new HashMap<>();
if (map.get("a") == null) {
map.put("a", new HashMap<>());
}
map.get("a").put("b", value);
If you don't need regular access to the entire "row", but just quick access to each cell you can use the built-in Map.Entry as your key:
Map<Map.Entry<String, String>, Object> table = new Map<>();
table.put(new Map.SimpleEntry("index1", "index2"), "Hello world");
Alternatively, if you're willing to go with something third-party, several someones have already implemented tuples for Java.
If you are in a situation where you cannot pull in a third-party library easily, but you don't like the semantics of Map.Entry (which is written in terms of keys and values) you can write your own Pair class to have the same effect.
As my understanding, you can do like:
Map<String, Map<String, Object> map= new HashMap();
Map<String, Object> subMap = map.get("index1");
if(subMap != null) {
Object obj = subMap.get("index2");
}
The best solution probably depends on how this map is intended to be used:
Is it used in a limited scope, or is it part of a public API?
Are the "indices" always of type String, or do they have to be generic?
Will it always be two indices, or may you need more indices later?
...
A pragmatic solution focussed on the question as you described it would be to introduce a StringPair class that can be used for indexing. This saves you from the hassle of doing 2D-lookups of inner maps (and possible cleanups when the inner maps become empty!), does not require any third-party libraries, and is readable and efficient.
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
public class StringPairMapTest
{
public static void main(String[] args)
{
Map<StringPair, Object> map = new LinkedHashMap<StringPair, Object>();
map.put(StringPair.of("A","B"), 12);
map.put(StringPair.of("C","D"), 34);
System.out.println(map.get(StringPair.of("A","B")));
System.out.println(map.get(StringPair.of("C","D")));
System.out.println(map.get(StringPair.of("X","Y")));
}
}
class StringPair
{
private final String s0;
private final String s1;
static StringPair of(String s0, String s1)
{
return new StringPair(s0, s1);
}
private StringPair(String s0, String s1)
{
this.s0 = s0;
this.s1 = s1;
}
#Override
public String toString()
{
return "("+s0+","+s1+")";
}
#Override
public int hashCode()
{
return Objects.hash(s0, s1);
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StringPair other = (StringPair) obj;
return Objects.equals(s0, other.s0) && Objects.equals(s1, other.s1);
}
}
Generalizations to a Pair<T> or Tuple<S,T> would be possible, of course, but this did not seem to be what you have been looking for...
Related
Maybe I am thinking something wrong here, but let's say I want to return a bunch of objects of different types. For example a lot of Persons, Profiles, Accounts. I wanted to put them in a map where a key would be something like Person.class and value would be a list of Person instances. First I thought about an EnumMap, but why should I create an ENUM for a list of classes, if I could somehow use the classes themselves?
I tried to get there with generics, but cannot wrap my head around the definition.
Is this even possible? Or am I thinking a bad design?
I could provide different methods for retrieval partial results. Or create a class that would hold it. But Map is more flexible, in case I want to use more classes in the future.
Edit:
I got some answers, which does not seem to address specifically what I am looking for, so for clarification:
I want something like:
{
Person.class : [person1Instance, person2Instance,...],
Account.class : [account1Instance, account2Instance, account3Instance, ...],
Profile.class : [profile1Instance...]
}
And I want to avoid casting. Somehow use the fact that the key should define type (safety) for the list of items.
I've implemented this in TypedMap: http://blog.pdark.de/2010/05/28/type-safe-object-map/
Here is some demo code:
TypedMap map = new TypedMap();
String expected = "Hallo";
map.set( KEY1, expected );
String value = map.get( KEY1 ); // Look Ma, no cast!
assertEquals( expected, value );
List<String> list = new ArrayList<String> ();
map.set( KEY2, list );
List<String> valueList = map.get( KEY2 ); // Even with generics
assertEquals( list, valueList );
The magic is in the key:
final static TypedMapKey<String> KEY1 = new TypedMapKey<String>( "key1" );
final static TypedMapKey<List<String>> KEY2 = new TypedMapKey<List<String>>( "key2" );
To solve your problem, you need to create keys for the different types that you want to save in the map:
TypedMapKey<List<Account>> ACCOUNTS = new TypedMapKey<List<Account>>( "ACCOUNTS" );
then you need the usual get/create code:
public <T> List<T> getList( TypedMapKey<List<T>> key ) {
List<T> result = map.get(key);
if(null == result) {
result = new ArrayList<T>();
map.put(key, result);
}
return result;
}
which will allow you to access the list with:
List<Account> accounts = getList(ACCOUNTS);
Object of different type are not allowed, because while retrieving them we face problem we don't know what type of object is going to come out.
This is my suggestion :
Make map like :
Map<Object, String> map = new HashMap<Object, String>();
Lets u put some values like :
Person p = new Person();
map.put(p, "Person");
Account a = new Account();
map.put(a, "Account");
Assuming you will pass different object.
While retrieving something like this :
for(Entry<Object, String> entry : map.entrySet()) {
String choiceClassName = entry.getValue();
switch(choiceClassName) {
case "Person" : Person p = (Person) entry.getKey();
break;
case "Account" : Account a = (Account) entry.getKey();
break;
}
}
You don't need any enums. You can just use the instanceof to check what type an object is. This is how I usally do it, but i'm curious about other answers by others.
Usually I only use one parent type with generic methods that I need for my maps(usually an interface).
But sometimes I use this method in cases where I really don't know what will be put into the map by user actions.
Take for example this map:
HashMap<String,Object> stuff = new HashMap<String,Object>();
stuff.add("joe",new Person());
stuff.add("new york", new City());
Iterator it = stuff.iterator();
while(it.hasNext()) {
Object obj = it.next();
if(obj instanceof Person) {
Person p = (Person)obj;
}
if(obj instanceof City) {
City c = (City)obj;
}
}
In the end I created my own TypedMultimap, using a hint from tobias_k comment.
I created this class:
import com.google.common.collect.ForwardingMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
/**
*
* #author mimkorn
*/
public class TypedMultimap extends ForwardingMultimap<Class, Object> {
private final HashMultimap<Class, Object> delegate;
public TypedMultimap() {
this.delegate = HashMultimap.create();
}
// IMPORTANT PART
public <T> Collection<T> getSafely(Class<T> key) {
return (Collection<T>) delegate().get(key);
}
public <T> boolean putSafely(
Class<T> key, T value) {
return delegate.put(key, value);
}
// TILL HERE
// CONVENIENCE
public <T> boolean putSafely(T value) {
return delegate.put(value.getClass(), value);
}
// TILL HERE
#Override
public Collection<Object> get(Class key) {
return getSafely(key);
}
#Override
public boolean put(Class key, Object value) {
return putSafely(key, value);
}
#Override
protected Multimap<Class, Object> delegate() {
return delegate;
}
}
Edit: Now you can just put(new SomeClass()); and it will put it into the map mapping it under the SomeClass.class. This way you only add data without caring about the class and the map will sort it out for you. Then you can fetch all instances of a particular type with <T> Collection<T> getSafely(Class<T> key)
Now when you call getSafely or putSafely it will check the types for you. The drawback is, that the user somehow needs to know, that he should add data with the single argument put method. Also, that only getSafely and putSafely, will check for compile time errors.
Now you can do this:
TypedMultimap typedMultimap = new TypedMultimap();
typedMultimap.putSafely(new ExportThing("prvý"));
typedMultimap.putSafely(new ExportThing("druhý"));
typedMultimap.putSafely(ExportThing.class, new ExportThing("prvý"));
typedMultimap.putSafely(new ExportPhoneNumber("prvý"));
typedMultimap.putSafely(ExportPhoneNumber.class, new ExportPhoneNumber("druhý"));
Collection<ExportPhoneNumber> safely = typedMultimap.getSafely(ExportPhoneNumber.class);
for (ExportPhoneNumber safely1 : safely) {
System.out.println(safely1.getPhoneNumber());
}
will return:
druhý
prvý
Trying to do
typedMultimap.putSafely(ExportThing.class, new ExportPhoneNumber("prvý"));
will result in a compile time error.
This is a somewhat Map>. If you need Map> use as the delegate ArrayListMultimap for example instead of HashMultimap
When writing a Java program, I face a problem as follows:
Map<Object, Map<Object, Map<Object, Object>>> map = new HashMap<>();
/**
* put operations
**/
Map<Object, Map<Object, Object>> a = null;
Map<Object, Object> b = null;
Object c = null;
a = map.get(/*some object*/);
if(a != null) {
b = a.get(/*some object*/);
}
if(b != null) {
c = b.get(/*some object*/);
}
if(c != null) {
/*do what I want to do*/
}
If I want to be sure c is not null, I need to add an "if" three times to ensure that the code can run without exception. Is there a better way to do it?
Encapsulate required functionality in a class implementing something like this:
interface ThreeKeysMap {
void put(Object keyA, Object keyB, Object keyC, Object value);
Object get(Object keyA, Object keyB, Object keyC);
}
Alternatively, you could create a class for your composite key:
public class ThreeKey {
public Object keyA;
public Object keyB;
public Object keyC;
// TODO: MUST override equals and hashCode methods or map won't work!!!!
}
and use it as a key for your map: Map<ThreeKey, Object> map = new HashMap<>();
I think that the getOrDefault-method of the Map interface could work here. Especially if you combine it with the Optional class as follows:
Map<Object, Map<Object, Map<Object, Object>>> map = new HashMap<>();
Map<Object, Map<Object, Object>> a = map.getOrDefault("", Collections.emptyMap());
Map<Object, Object> b = a.getOrDefault("", Collections.emptyMap());
Optional.ofNullable(b.get("")).ifPresent(c -> {/* Do what I want to do */});
This way you simply use getOrDefault to retrieve empty maps (which I personally like better than null values. The Optional.ofNullable is a null-safe way of creating an Optional object and you can do what you want to do in the lambda expression.
Both Optional and Map.getOrDefault are part of Java 8.
You can create a class Key<T,E> that will hold your first pairs of objects, and than create a map
Map<Key<T,E>, Object>
This seems much more neat to me, because it seems you use the first two objects as a key, and the nested dictionary approach is less elegant for such a task.
Remember that if you follow this approach - you have to override equals() and hashCode(), and depending on usages - sometimes also compareTo()
Can I access my nestedMap in my iterator when the nestedMap is created in the put() method, like this:
#Override
public String put(final String row, final String column, final String value) {
/**
* Second map which is contained by centralMap, that contain Strings as
* Keys and Values.
*/
Map<String, String> nestedMap;
if (centralMap.containsKey(row))
nestedMap = centralMap.get(row);
else
nestedMap = new HashMap<String, String>();
if (!nestedMap.containsKey(column))
counter++;
centralMap.put(row, nestedMap);
return nestedMap.put(column, value);
}
and the centralMap is declared as an Object-Variable,
private final Map<String, Map<String, String>> centralMap;
but instantiated just in the constructor, like this:
centralMap = new HashMap<String, Map<String, String>>();
the method i'm trying to implement is the remove method:
#Override
public void remove() {
for (Map<String, String> map : centralMap.values()) {
map = centralMap.get(keyName);
iteratorNested.remove();
if (map.size() <= 0)
iteratorCentral.remove();
}
}
Thanks a lot!
Not sure what you're asking exactly, but I think this is a little easier to read:
#Override
public String put(final String row, final String column, final String value) {
/**
* Second map which is contained by centralMap, that contain Strings as
* Keys and Values.
*/
Map<String, String> nestedMap = centralMap.get(row);
if (nestedMap == null) {
nestedMap = new HashMap<String, String>();
centralMap.put(row,nestedMap);
}
if (!nestedMap.containsKey(column))
counter++;
centralMap.put(row, nestedMap);
return nestedMap.put(column, value);
}
I can't quite understand what you're doing in the second stanza, so can't help you improve that. And I don't see an iterator as referred to in your question.
You're making me guess, but maybe ELSEWHERE in your program (it would really help to see more code, and a specific function prototype or statement of behavior you're seeking) you want to be able to iterate through the contents of the centralMap instance, and nested instances of nestedMap. Yes you can.
public void iterateOverAllNested()
{
for (Map.Entry<String,Map<String,String>> nested : centralMap) {
final String centralKey = nested.key();
final Map<String,String> nestedMap = nested.value();
System.out.println("Central map row/column: "+centralKey);
for (Map.Entry<String,String> entry : nestedMap) {
System.out.println(" key="+entry.key()+", value="+entry.value());
}
}
}
Note that this smells. Nested maps of untyped Strings are probably wrong. Any chance you've been writing Perl recently? I suggest you write a second SO question asking about a good data structure for your specific problem. You can include this code as your starting place, and folks will likely offer a cleaner solution.
I would like to know: how can I iterate through a 2D map? I have a centralMap:
private final Map<String, Map<String, String>> centralMap =
new HashMap<String, Map<String, String>>();
which contains another map:
Map<String,String> nestedMap = new HashMap<String, String>();
as Value, and the second one is created in the "put" method, so that in the constructor, i have just the centralMap. Now i want to redefine this method and to get complete entry of the map (the 2 keys and the value for each element)
public Iterator<Entry> iterator()
How should I proceed? If possible, how can I remove an element through the iterator without having a problem?
Iterators are meant to operate on a collection, such as the keyset of your first map, or the values (which are a collection of maps) of your nested one. You cannot expect the iterator renove method to understand your complex structure.
I would suggest that you build your own class for this, with your own convenience methods that do what you described.
Also, going on a limb here: make sure you didn't just want to have a multimap. If so, have a look, for example, at guava's HashMultimap
You apply the same procedure as if you were iterating over a single map, you just do it twice:
public void printNestedMap(Map<String, Map<String, String>> map)
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next(); // <- pairs.getValue() is a map
System.out.println("Key1: " + pairs.getKey());
//print the inner Map
printMap((Map<String, String>)pairs.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
EDIT
It would actually be better to move the iteration over a single map to a different method to be called in this scenario.
public void printMap(Map<String, String>> map)
{
Iterator it = map.entrySet().iterator();
while(it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next(); // <- pairs.getValue() is a String
System.out.println("Key2: " + pairs.getKey() + " Value2: " + pairs.getValue());
it.remove();
}
}
EDIT 2: Test Program
import java.util.*;
public class TestMap
{
public static void main(String[] args)
{
Map<String, String> innerMap = new HashMap<>();
Map<String, Map<String, String>> outerMap = new HashMap<>();
innerMap.put("Key1", "Val1");
innerMap.put("Key2", "Val2");
innerMap.put("Key3", "Val3");
innerMap.put("Key4", "Val4");
outerMap.put("OuterKey1", innerMap);
printNestedMap(outerMap);
}
public static void printNestedMap(Map<String, Map<String, String>> map)
{
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next(); // <- pairs.getValue() is a map
System.out.println("Key1: " + pairs.getKey());
//print the inner Map
printMap((Map<String, String>)pairs.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
public static void printMap(Map<String, String> map)
{
Iterator it = map.entrySet().iterator();
while(it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next(); // <- pairs.getValue() is a String
System.out.println("Key2: " + pairs.getKey() + " Value2: " + pairs.getValue());
it.remove();
}
}
}
Output:
Key1: OuterKey1
Key2: Key2 Value2: Val2
Key2: Key1 Value2: Val1
Key2: Key4 Value2: Val4
Key2: Key3 Value2: Val3
If you want to get Map.Entry elements containing the two keys and the value, it will really be much more natural to create a class Pair<String, String> that combines the two keys in a single element and use that as the key in a single map rather than nesting maps.
If you do this, your main structure will be a Map<Pair<String, String>, String> and using the Map.entrySet() method will give you a Set<Map.Entry<String, String>, String> from which you can get an iterator that gives approximately what you're after.
If you need to have a Map<String, Map<String, String>> for other reasons, it is also possible to convert this into the structure described above by reasonably simple code, and this might be the most sensible way of getting the information out of it.
Edit Note:
The Pair class described above is essentially the same as Map.Entry, so you could avoid creating a new class for the key by building a Map<Map.Entry<String, String>, String>. I think it makes the code a bit less clear, but it can certainly be made functionally equivalent.
Sample Code
In the code below, I have defined the Pair class as an inner static (for real use, you might want to extract as an independent class), and written a conversion that takes a nested map as you describe, converts it to the form I've suggested, and uses an iterator on the entries of the converted map to print the values.
The iterator could of course be used for other things, and the convert method and Pair class are generic.
import java.util.*;
public class TestMap
{
public static void main(String[] args)
{
Map<String, String> innerMap1 = new HashMap<String, String>();
Map<String, String> innerMap2 = new HashMap<String, String>();
Map<String, Map<String, String>> outerMap = new HashMap<String, Map<String, String>>();
innerMap1.put("InnerKey1", "Val1");
innerMap1.put("InnerKey2", "Val2");
innerMap1.put("InnerKey3", "Val3");
innerMap1.put("InnerKey4", "Val4");
innerMap2.put("InnerKey5", "Val5");
innerMap2.put("InnerKey6", "Val6");
innerMap2.put("InnerKey7", "Val7");
innerMap2.put("InnerKey8", "Val8");
outerMap.put("OuterKey1", innerMap1);
outerMap.put("OuterKey2", innerMap2);
Map<Pair<String, String>, String> convertedMap = convert(outerMap);
for (Map.Entry<Pair<String, String>, String> entry: convertedMap.entrySet()) {
System.out.println(String.format("OuterKey: %s, InnerKey: %s, Value: %s",
entry.getKey().getFirst(),
entry.getKey().getSecond(),
entry.getValue()
));
}
}
private static <K1,K2,V> Map<Pair<K1, K2>,V> convert(Map<K1, Map<K2,V>> nestedMap) {
Map<Pair<K1, K2>, V> result = new HashMap<Pair<K1, K2>, V>();
for (Map.Entry<K1, Map<K2, V>> outerEntry: nestedMap.entrySet()) {
final K1 outerKey = outerEntry.getKey();
for (Map.Entry<K2, V> innerEntry: outerEntry.getValue().entrySet()) {
final K2 innerKey = innerEntry.getKey();
final V value = innerEntry.getValue();
result.put(new Pair<K1, K2>(outerKey, innerKey), value);
}
}
return result;
}
public static class Pair<T1, T2> {
private T1 first;
private T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public T1 getFirst() {
return first;
}
public T2 getSecond() {
return second;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair pair = (Pair) o;
if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
if (second != null ? !second.equals(pair.second) : pair.second != null) return false;
return true;
}
#Override
public int hashCode() {
int result = first != null ? first.hashCode() : 0;
result = 31 * result + (second != null ? second.hashCode() : 0);
return result;
}
}
}
Note on Usage in context:
In your current code, you have a class with a field centralMap which is the map in your old nested form, and an integer counter for the size of the map.
This containing class has a method for adding entries that looks like this:
#Override
public String put(final String row, final String column, final String value) {
/**
* Second map which is contained by centralMap, that contain Strings as Keys
* and Values.
*/
Map<String, String> nestedMap;
if (centralMap.containsKey(row))
nestedMap = centralMap.get(row);
else
nestedMap = new HashMap<String, String>();
if (!nestedMap.containsKey(column))
counter++;
centralMap.put(row, nestedMap);
return nestedMap.put(column, value);
}
If instead of using the nested map at all, you change this field to a map of the suggested form, this method would become a bit simpler:
#Override
public String put(final String row, final String column, final String value) {
Pair<String, String> key = new Pair(row, column);
if (centralMap.contains(key)
counter++;
centralMap.put(key, value);
}
And you actually wouldn't need the counter anymore, as it will always contain the same value as centralMap.size().
Update:
From edits put in yesterday but now deleted, it's now clear to me (from edit history) that you want to build a single iterator that delegates to all the iterators of the map in correct sequence, and returns a simple structure containing both keys and the value.
This is certainly possible, and if I have time later, I might add some sample code for it. As was noted in another response, the iterator.remove() method may be impossible or unnatural.
Meanwhile, your requirements (as noted a comment on the same other response) is rather similar to what is supplied by guava's Table. That's open source, and looking at it may give you ideas. You can download the source for guava here.
Specifically, in guava's StandardTable, there is an inner class CellIterator, which looks like:
private class CellIterator implements Iterator<Cell<R, C, V>> {
final Iterator<Entry<R, Map<C, V>>> rowIterator
= backingMap.entrySet().iterator();
Entry<R, Map<C, V>> rowEntry;
Iterator<Entry<C, V>> columnIterator
= Iterators.emptyModifiableIterator();
#Override public boolean hasNext() {
return rowIterator.hasNext() || columnIterator.hasNext();
}
#Override public Cell<R, C, V> next() {
if (!columnIterator.hasNext()) {
rowEntry = rowIterator.next();
columnIterator = rowEntry.getValue().entrySet().iterator();
}
Entry<C, V> columnEntry = columnIterator.next();
return Tables.immutableCell(
rowEntry.getKey(), columnEntry.getKey(), columnEntry.getValue());
}
#Override public void remove() {
columnIterator.remove();
if (rowEntry.getValue().isEmpty()) {
rowIterator.remove();
}
}
}
You can't just copy this code as it depends on other things in guava, but it shows the basic pattern of what you have to do.
I am using a Javascript object as an object with configuration properties.
E.g. I have this object in javascript:
var myProps = {prop1: 'prop1', prop2: 'prop2', 'prop3': 'prop3'};
This object (NativeObject) is returned to me in Java function.
E.g.
public Static void jsStaticFunction_test(NativeObject obj) {
//work with object here
}
I want to get all properties from object and build HashMap from it.
Any help will be appreciated.
So, I solved my problem :)
Code:
public static void jsStaticFunction_test(NativeObject obj) {
HashMap<String, String> mapParams = new HashMap<String, String>();
if(obj != null) {
Object[] propIds = NativeObject.getPropertyIds(obj);
for(Object propId: propIds) {
String key = propId.toString();
String value = NativeObject.getProperty(obj, key).toString();
mapParams.put(key, value);
}
}
//work with mapParams next..
}
well, if you looked closer, you would have seen that NativeObject implements the Map interface, so you could have worked very well with the NativeObject.... But to answer your question: you could have used the common approach for getting the key-value pairs of any map
for (Entry<Object, Object> e : obj.entrySet()){
mapParams.put(e.getKey().toString(), e.getValue().toString());
}
A cast would have been enough for your case, because you have only strings as values. So, if you really wanted a HashMap:
HashMap<String, String> mapParams = new HashMap<String, String>((Map<String,String>)obj); //if you wanted a HashMap
But if you just wanted a generic Map, it was even simpler, and less RAM consuming:
Map<String, String> mapParams = (Map<String,String>)obj;