21

If I have class like this:

class MyObject {
    public int myInt;
    public String myString;
}

Is it possible to convert instance of this class to HashMap without implementing converting code?

MyObject obj = new MyObject();
obj.myInt = 1; obj.myString = "string";
HashMap<String, Object> hs = convert(obj);

hs.getInt("myInt"); // returns 1
hs.getString("myString"); // returns "string"

Does Java provide that kind of solution, or I need to implement convert by myself?

My Class has more than 50 fields and writing converter for each field is not so good idea.

6
  • 1
    Hashmaps have keys and values (2 things), rather than 50 fields. Can you clarify what you are trying to achieve here? Commented May 4, 2016 at 9:59
  • you´d also have to provide a custom Map implementation, because the valid method to get the value for a key from the Map is the get(Object) method. There is nothing like getInt or getString in order to return different types from the Map.In the end it wouldn´t make any sense to have them, because the return type is defined by the second generic type. Commented May 4, 2016 at 9:59
  • @TimBiegeleisen I want to convert all fields of my object to keys and values of hashmap. Commented May 4, 2016 at 10:02
  • @Mr.D could you eleborate a usecase for this, because i can´t see any. Calling a simple getter method would be more easy to me, especially since changing a single value in any of this fields would make the formerly generated Map an invalid one. Commented May 4, 2016 at 10:04
  • 1
    @KevinEsche there are some libs which accept only hashmaps Commented May 4, 2016 at 10:07

6 Answers 6

28

With jackson library this is also possible

MyObject obj = new MyObject();
obj.myInt = 1;
obj.myString = "1";
ObjectMapper mapObject = new ObjectMapper();
Map < String, Object > mapObj = mapObject.convertValue(obj, Map.class);
Sign up to request clarification or add additional context in comments.

2 Comments

To me, this is the quickest and less prone to error solution. Here is a reference with a more complete example using this solution mkyong.com/java/java-convert-object-to-map-example
One caveat is that this solution will not keep the enum values type, it will transform them to String name /or index.
10

You can use reflection for implementing this behavior. You can get all fields of the class you want to convert to map iterate over this fields and take the name of each field as key of the map. This will result in a map from String to object.

Map<String, Object> myObjectAsDict = new HashMap<>();    
Field[] allFields = SomeClass.class.getDeclaredFields();
    for (Field field : allFields) {
        Class<?> targetType = field.getType();
        Object objectValue = targetType.newInstance();
        Object value = field.get(objectValue);
        myObjectAsDict.put(field.getName(), value);
    }
}

2 Comments

If some fields are Lists of objects? How to "reflect" them?
If the object relations form a tree and not a graph you can use the method described here stackoverflow.com/questions/6133660/…
5

Something like that will do the trick:

MyObject obj = new MyObject();
obj.myInt = 1; obj.myString = "string";
Map<String, Object> map = new HashMap<>();
// Use MyObject.class.getFields() instead of getDeclaredFields()
// If you are interested in public fields only
for (Field field : MyObject.class.getDeclaredFields()) {
    // Skip this if you intend to access to public fields only
    if (!field.isAccessible()) {
        field.setAccessible(true);
    }
    map.put(field.getName(), field.get(obj));
}
System.out.println(map);

Output:

{myString=string, myInt=1}

Comments

0

You might consider using a map instead of a class.

Or have your class extend a map such as

public class MyObject extends HashMap<String, Object> {

}

Comments

0

If you don't want to use Reflection then you can use my trick. hope this may help for someone.

Suppose your class looks like this.

public class MyClass {
         private int id;
         private String name; 
}

Now Override toString() method in this class. in Eclipse there is a shortcut for generating this method also.

public class MyClass {
    private int id;
    private String name; 

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("MyClass [id=").append(id).append(", name=").append(name).append("]");
        return builder.toString();
    }

}

Now write a method inside this class that will convert your object into Map<String,String>

public Map<String, String> asMap() {
        Map<String, String> map = new HashMap<String, String>();
        String stringRepresentation = this.toString();
        if (stringRepresentation == null || stringRepresentation.trim().equals("")) {
            return map;
        }
        if (stringRepresentation.contains("[")) {
            int index = stringRepresentation.indexOf("[");
            stringRepresentation = stringRepresentation.substring(index + 1, stringRepresentation.length());
        }
        if (stringRepresentation.endsWith("]")) {
            stringRepresentation = stringRepresentation.substring(0, stringRepresentation.length() - 1);
        }
        String[] commaSeprated = stringRepresentation.split(",");
        for (int i = 0; i < commaSeprated.length; i++) {
            String keyEqualsValue = commaSeprated[i];
            keyEqualsValue = keyEqualsValue.trim();
            if (keyEqualsValue.equals("") || !keyEqualsValue.contains("=")) {
                continue;
            }
            String[] keyValue = keyEqualsValue.split("=", 2);
            if (keyValue.length > 1) {
                map.put(keyValue[0].trim(), keyValue[1].trim());
            }

        }
        return map;
    }

Now from any where in your application you can simply call this method to get your HashMap from the Object. Cheers

Comments

0

Updated approach using reflection:

  public static <T> Map<String, String> parseInnerClass(T classInstance) {
    LinkedHashMap<String, String> ret = new LinkedHashMap<>();

    for (Field attr : classInstance.getClass().getDeclaredFields()) {
      String attrValue = "";
      attr.setAccessible(true);

      try {
        attrValue = attr.get(classInstance).toString();
      } catch (IllegalAccessException | NullPointerException e) {
        // Do not add nothing
      }

      ret.put(attr.getName(), attrValue);
    }
    return ret;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.