Reputation: 71
I have a nested collection in the form:
HashMap<String, HashMap<String, List<String>>> errorList;
Now I initialize it inline using double braces like this
errorList.put(tempName, new HashMap<String, List<String>>() {{
put("upl", new ArrayList<String>() {{ add("Y"); add("Upload Success"); }});
}});
This lies in a foreach loop with the value of tempName
changing in every iteration.
I did this because i couldn't use instances of List<String>
or HashMap<String,List<String>>
because every time i changed the value in that instance it is reflected in the collection it is nested in. So i am forced to create new instances with double brace initialization.
Thing is: I want to use a list object. Instead of
new ArrayList<String>() {{ add("Y"); add("Upload Success"); }}
I want to use a variable.
How can I do this?
Upvotes: 4
Views: 3003
Reputation: 86262
Instead of:
new ArrayList<String>() {{ add("Y"); add("Upload Success"); }}
you may use:
Arrays.asList("Y", "Upload Success")
This gives you a fixed-size list.
Or since Java 9 just:
List.of("Y", "Upload Success")
This gives you a completely immutable list.
If you want to be able to modify the list later (in the former case if you want to be able to add or remove elements), convert it into an ArrayList
:
new ArrayList<>(Arrays.asList("Y", "Upload Success"))
or
new ArrayList<>(List.of("Y", "Upload Success"))
And of course you can put this list into its own variable before putting it into your map structure.
If you want to put either [Y, Upload Success]
or [N, Upload Failed]
and make sure the lists aren’t shared between map entries, here’s a suggestion: First, outside your loop:
final List<String> successList = List.of("Y", "Upload Success");
final List<String> failureList = List.of("N", "Upload Failed");
Then inside your loop:
if (wasSuccessful) {
errorList.put(tempName,
Collections.singletonMap("upl", new ArrayList<>(successList)));
} else {
errorList.put(tempName,
Collections.singletonMap("upl", new ArrayList<>(failureList)));
}
Or since Java 9 use Map.of()
:
if (wasSuccessful) {
errorList.put(tempName,
Map.of("upl", new ArrayList<>(successList)));
} else {
errorList.put(tempName,
Map.of("upl", new ArrayList<>(failureList)));
}
You may take the idea one step further and build the maps outside the loop. And again, if you want the inner map to be a HashMap
, just convert into one: new HashMap<>(Map.of("upl", new ArrayList<>(successList)))
.
You notice I have avoided the double brace initialization completely. While it’s brief, it has an overhead both conceptually and performancewise. You are creating a new anonymous subclass each time, which I don’t find warranted.
Upvotes: 6