JavaRush /Java Blog /Random EN /Double brace initialization
Joysi
Level 41

Double brace initialization

Published in the Random EN group

1. Double brace initialization

Initialization using double braces ( hereinafter referred to as Double brace initialization ) is a Java tool for creating collections such as list, set and map simultaneously with their declaration.
Double brace initialization - 1
When you need lists with fixed elements, such as a list of supported products or currencies, declaring the list at the same time as initializing it improves code readability. This is why Double brace initialization is gaining popularity, since there are no other standard methods for creating collections with simultaneous initialization in code. Unfortunately, unlike other programming languages, Java does not support collections of literals. Due to this limitation, creating an unmodifiableList with even a small number of elements forces us to write many lines of code in the form of repeated calls add()to add the desired elements with final wrapping:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
This is an unnecessarily redundant description that could be simplified. Let's fill static lists in a way convenient for us, namely directly in static blocks during initialization, which is what Double braceinitialization will help us with, allowing us to write everything in one line:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
Similarly, Double braceinitialization will help us fill in values ​​and HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
It all looks so elegant, but it has its drawbacks, which make Double brace initialization an anti-pattern. We will look at them further in the next chapter.

Pros and cons of Double brace initialization.

Doublebrace initialization uses the creation of an anonymous inner class . What is initially hidden on the surface, however, Double braceinitialization creates a class with further initialization of its instance every time you use it. In addition, a hidden reference to this private class is used, which can lead us to possible memory leaks. You also cannot use the ghost operator for generics (diamond operator < >), since we cannot access the inside of an anonymous class.
(From the translator: Once again in more detail:
after the first {, an internal anonymous class is created, after the second, {initialization occurs when creating an instance of the class, in which we have access to the fields and methods of the external (relative to the anonymous) class.)
Pros:
  1. Reducing lines in code
  2. Creation and initialization in one expression.
Minuses:
  1. Creating an anonymous class hidden from you.
  2. Which costs us additional costs for its instance every time we use it.
  3. Each time a hidden reference to it is created, which may lead to memory leaks.
Verdict: Due to the above cons and the existence of alternatives to Double brace, initialization is considered an anti-pattern in the Java world. Save the kitten

Alternatives to Double brace initialization in Java

The good news is that there are other ways to achieve the same goals in Java. We can implement in one line of code the creation and initialization of an ArrayList using the Copy constructor from the Collection class as shown below:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()will return us a list of fixed length passed to ArrayListthe copy constructor. Keep in mind the difference between fixed-length lists returned from Arrays.asList()and Collections.unmodifiableList(): you can't add or remove elements ArrayListof - , but you can change an element by index using set(), which you can't do with a list returned by Collections.unmodifiableList(). If you want to get a small list, this is the best way, although it will be less transparent for Setother collections, so you will have to create it Listbefore creating Set-a. But this is still better than Double brace initialization, since in this case an extra internal anonymous class is not created every time it is used. If you are running Java 8 you have another alternative method. The JDK 8 Stream API will help you create small collections by combining output Stream Factorymethods into a collection List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
For Setyou can use Collectors.toSet()the method instead Collectors.toList()as below:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
By the way, Stream collectmethods do not guarantee that the collections they generate are protected from changes. In Java 8, the collections they returned (such as - ArrayList, HashSet, and HashMap) are quite common (we can change them), but this fact may be corrected in future JDK releases. That's all for now about Double braceinitialization in Java. This template is acceptable for tests and demos, but not good enough for production use. Due to its inherent disadvantages, Double brace initialization has become an anti-pattern these days, especially given the alternatives available. I myself still use this construction to initialize static maps and that’s it. For ListI prefer to create Collectionsby combining with creating Array.asListin its constructor. And if I use Java 8 - a design using the Stream API and collect(). Related Articles: If you enjoyed this tutorial and want to learn more about Java programming patterns, principles, and best practices, you may also want to check out the other articles on our site . Recommended Reading: If you want to learn more about patterns and best practices you should read Effective Programming by Joshua Bloch , no book can take its place. And if you are already proficient in Java and are looking for a book on design patterns, the humorous style of presentation of which is interesting and easy to read, pay attention to “Head First. Design Patterns" .
From the translator: I deliberately provided a link to Bloch’s original book, since its translation into Russian is unsuccessful (for example, Builder = constructor).
Translation of the article What is Double Brace Initialization in Java? Anti Pattern Example (published October 2015).
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION