how and when HashMap initialize entrySet and add value into it

It is your debugger that fools you. The debugger view calls toString() which in fact calls entrySet() (see AbstractMap.toString()). That is why the entrySet was already initialized, when you looked at it.

If you look in there via reflection utils, e.g. with the following code:

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

Field entrySetField = HashMap.class.getDeclaredField("entrySet");
entrySetField.setAccessible(true);
Object entrySet = entrySetField.get(map);
System.out.println("entrySet = " + entrySet);
System.out.println("map.toString() = " + map.toString());
entrySet = entrySetField.get(map);
System.out.println("entrySet = " + entrySet);

you get the following output:

entrySet = null
map.toString() = {}
entrySet = []

As you can see: entrySet in fact is still null if no toString() is called and gets initialized after it.

The same applies to your second question. If you look at the values "reflectively":

// Starting from where my entrySet is still null
map.put("key", "value");
entrySet = entrySetField.get(map);
System.out.println("entrySet = " + entrySet);

you get, as expected:

entrySet = null

Tags:

Java

Hashmap