1

I want to declare a HashMap with another HashMap as its value type. I have this code, and it doesn't work:

private HashMap<String, String> ContactData= new HashMap<String, String>();
private HashMap<String, String> Messages= new HashMap<String, String>();
private HahsMap<String, Messages> MessegesStructure= new HashMap<String, Messages>();

This is the Error I get in console:

Error:(10, 29) java: cannot find symbol
  symbol:   class Messages
  location: class com.company.ContactClass
Error:(10, 78) java: cannot find symbol
  symbol:   class Messages
  location: class com.company.ContactClass
Error:(10, 13) java: cannot find symbol
  symbol:   class HahsMap
  location: class com.company.ContactClass

This code doesn't compile. How can I make it work?

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
Morin
  • 43
  • 4
  • Please use clear English language when you're asking the question; then, at least try your code in your IDE before posting it here; finally - yes, you can embed any collection into any other collection. – Giorgi Tsiklauri Jul 18 '20 at 06:08
  • Hi, thank you, It is clear I tried my code in IDE, and I gave error from that, and my reason for asking this question is that. The English language is not my first language, and obviously, I can not speak English fluently, but I attempt to improve my speaking skill. Would you please take an example of HashMap in HashMap for me? – Morin Jul 18 '20 at 06:22
  • In that case you should upload your code, and the error message you have. This way you'll tell the audience what you have done so far, what is the problem, and what you're aiming for. See the answer I just wrote for you. – Giorgi Tsiklauri Jul 18 '20 at 06:29
  • I've updated your question, it's not clear, understandable and grammatically correct. You can upvote for my answer if it helped you. – Giorgi Tsiklauri Jul 18 '20 at 06:45
  • 1
    Yeah, I understand it, thanks – Morin Jul 18 '20 at 06:50

3 Answers3

2

What you're doing in your code is both - semantically and syntactically incorrect. I'd suggest you to learn basics of Java, as it seems like you're unaware of what is type and declaration.

You have to use SomeType when declaring your variable. Using reference (or any other) variable as the type, doesn't make any sense and will not be compiled. Your reference variable is a variable, which has a reference to the object, it's not a valid logic to declare (or define) your variable with another variable.


To answer your question about embedding Type into your generic type: Yes, you can have any type as either a key or a value declaration.

2 level depth HashMap, value type of which is another HashMap, looks like this:

HashMap<String, HashMap<String, HashMap>> twoLevelDepthEmbeddedHashMap 
= new HashMap<String, HashMap<String, HashMap>>();

3 level depth HashMap, value type of which is another HashMap with, in turn, its value type of HashMap, looks like this:

HashMap<String, HashMap<String, HashMap<String, String>>> threeLevelDepthEmbeddedHashMap
= new HashMap<String, HashMap<String, HashMap<String, String>>>();

Note 1: If you're trying this for the learning purposes, then it's OK; however, try to avoid this embedding design in the real life scenarios;

Note 2: Please don't capitalize first letters of your variable names. According to Java Code/Naming Conventions, PascalCase for the variables is not OK.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
1

You are getting error because you are using object as type.

private HashMap<String, Messages> MessegesStructure= new HashMap<String, Messages>();

Here Messages is an object of HashMap<String, String> that's the problem. Use type HashMap<String, String> instead of Messages

private HashMap<String, HashMap<String, String>> MessegesStructure= new HashMap<String, HashMap<String, String>>();

Note: Try to name object start with small letter.

Eklavya
  • 17,618
  • 4
  • 28
  • 57
1

You could use extension to introduce the type

    class Messages extends HashMap<String, String> {};
    HashMap<String, Messages> messageStructure = new HashMap<>();

such that

    /*
     * Usage
     */
    Messages messages = new Messages();
    messages.put("someKey", "someValue");
    messages.put("someOtherKey", "someOtherValue");
    
    messageStructure.put("someMessagesKey", messages);
    
    messageStructure.forEach((key,value) -> System.out.println(key + "\t" + value));

prints

someMessagesKey {someOtherKey=someOtherValue, someKey=someValue}

On the other hand, I would prefer composition, that is

    class Messages {
        private HashMap<String, String> messages = new HashMap<>();
        
        public void put(String key, String value) {
            messages.put(key, value);
        }

        @Override
        public String toString() {
            return "Messages [messages=" + messages + "]";
        }
    }
    
    HashMap<String, Messages> messageStructure = new HashMap<>();

because that would allow to change the underlying data structure of your "Messages" implementation later.

Christian Fries
  • 16,175
  • 10
  • 56
  • 67
  • Yeah exactly, This is one of the features of my application that I work on it, that each user able to extend the messages note according to the content. Your idea is brilliant. Thanks for your comprehensive guide. – Morin Jul 18 '20 at 09:11