3

New to Java and was curious if there was a way to make the Value of a HashMap either a string or an ArrayList:

HashMap<String, HashMap<String, ArrayList<String>>> map = new HashMap<String, HashMap<String, ArrayList<String>>>();
map.putIfAbsent("238991", new HashMap<String, ArrayList<String>>());
map.get("238991").put("OrderID", new ArrayList<>());
map.get("238991").get("OrderID").add("1234H");
map.get("238991").get("OrderID").add("1233B");
map.get("238991").put("Name", new ArrayList<>());
map.get("238991").get("Name").add("Smith, John");
System.out.println(map.get("238991"));
System.out.println(map.get("238991").get("Name").get(0));

I would prefer to only add a String if I can for the Name rather than just accessing the first element of the list. Is this possible?

6
  • 1
    Could you please elaborate on what you're trying to do? o.O Commented Jul 14, 2016 at 13:55
  • 1
    Either/or? No, unless you create a StringOrArrayList type, and implement the disjoint union logic yourself. Commented Jul 14, 2016 at 13:57
  • In python, I can create nested dictionaries, this is kind of what I'm trying to do. There is a single id that is associated with a number of different properties. I'm putting them into a HashMap so that I can iterate through them and access the elements to put into a full string. There are multiple OrderIDs per UserID number (238991) but there is only 1 name. Each OrderID will then have 3 or 4 strings associated with it. My goal is to concat all of the strings associated with all of the OrderIDs for 1 UserID number. Commented Jul 14, 2016 at 13:59
  • 1
    Java aint python. There are types. Commented Jul 14, 2016 at 14:05
  • String and ArrayList are both subtypes of Object - you could just have a hashmap with value type Object. This is not a recommendation. But you could do that - throw away the typing and just have an anything-container like Python's dict. Commented Jul 14, 2016 at 14:10

4 Answers 4

2

You should create a POJO, and use it as the HashMap value. It can contain all the data you need. Writing "pythonic" code in Java is just as bad, as doing it the other way around.

Sign up to request clarification or add additional context in comments.

1 Comment

I had an object Class already created, I was trying to reinvent the wheel when I wanted them to be in a nested dict, not necessary in Java.. cool, thanks
0

The answer is probably no.

I say "probably" because this:

System.out.println(map.get("238991").get("Name").toString());

will print:

[Smith, John]

This works because the ArrayList.toString() method will format the list. However, that is probably not what you want because:

  • there are square brackets around the name, and
  • the if you have more than one element in the list you will get all of them; e.g.

    map.get("238991").get("Name").add("Jones, Barry");
    
    [Smith, John, Jones, Barry]
    

2 Comments

Is there a better way to ultimately get a nested key/value pair of various object types than a HashMap?
Not that I am aware of. However, if you find yourself doing this kind of thing a lot, it probably means that you are not thinking in Java. The "Java way" is to create classes rather than to represent data structures by nesting open collection types. (Java isn't Python ...)
0

You should work with POJOs. Create a class that coveres your needs is much more feasible.

main.class

import java.util.ArrayList;
import java.util.HashMap;

public class OwnClass {

    public static void main(String[] args) {
        HashMap<String, Order> map = new HashMap<>();
        ArrayList<String> orderItems = new ArrayList<>();
        orderItems.add("1234H");
        orderItems.add("1234B");
        map.putIfAbsent("238991", new Order("Smith, John", orderItems));


        map.get("238991").addOrder("1234J");

        System.out.println(map);
    }
}

Order.class

import java.util.ArrayList;

public class Order {

    private String customer;
    private ArrayList<String> items;

    public Order(String string, ArrayList<String> orderItems) {
        this.customer = string;
        this.items = orderItems;
    }

    @Override
    public String toString() {
        return "Customer " + customer + " ordered " + items;
    }

    public void addOrder(String string) {
        items.add(string);
    }

}

Output:

{238991=Customer Smith, John ordered [1234H, 1234B, 1234J]}

Comments

0
import java.util.*;

public class MapReceivesListOrString{

public static void main(String []args){

   boolean shouldAddList = true;

   Map<String, Object> map = new HashMap<String, Object>(); //Creating a HashMap Polymorphically
   List<String> list = new ArrayList<>();

   list.add("1234H");
   list.add("1233B");

   String code1 = "some code one";
   String code2 = "some code two";

   if (shouldAddList) { // Your business logic whether to add a list or a string
       map.put("OrderID", list);        
   } else {
       map.put("code1", code1);
       map.put("code2", code2);
   }

   for (Map.Entry<String, Object> mapValues : map.entrySet()) { // Iterate over many list's or many string's
       Object value = mapValues.getValue();

       if (value instanceof List) {
            ArrayList myList = (ArrayList) value;

           System.out.println("List value one: " + list.get(0));
           System.out.println("List value two: " + list.get(1));
       } else {
           System.out.println("String value: " + value.toString());
       }
   }
}

}

Based on the existance of java generics we should define a specific type e.g. <String, ArrayList> rather than <String, Object> nonetheless it is a completely valid syntax.

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.