Double dyad initialization is a Java idiom to initialize a Collection similar a list, laid in addition to map at the fourth dimension of declaration. At times, y'all need a listing of fixed elements e.g. supported products, supported currencies or roughly other config, in addition to on the location initialization reduces draw of code in addition to improves readability. Double dyad initialization idiom becomes pop because in that location is no touchstone way to create in addition to initialize Collection at the same fourth dimension inwards Java. Unfortunately, dissimilar roughly other language, Java doesn't back upward collection literals yet. Due to this limitation, creating an unmodifiable List amongst minor numbers of elements requires many lines of code involving creating list, repeatedly calling add() method to add together those elements in addition to thus survive wrapping it into unmodifiable listing every bit shown below :
This is quite verbose, in addition to because it cannot live expressed inwards a unmarried expression, static lists must live populated inwards static initializer blocks rather than via a to a greater extent than convenient plain initializer.
Double dyad initialization idiom tin produce this inwards only 1 draw every bit shown below:
You tin likewise initialize HashMap amongst values using double dyad initialization every bit following:
This looks pretty, but it has its ain laid of disadvantages, which made it an anti-pattern, we'll run into them inwards side past times side section.
Pros:
1) Less draw of code
2) Creation in addition to Initialization inwards the same expression
Cons:
2) Obscure, internally uses the instance initializer create of the anonymous class.
2) It terms an extra shape every fourth dimension y'all piece of work it
3) It holds a hidden reference to the enclosing instance, which may motility memory leaks.
Due to its disadvantage in addition to ameliorate choice double dyad initialization is straightaway considered every bit an anti-pattern inwards Java world.
Arrays.asList() returns a fixed length list, which is passed to ArrayList re-create constructor. Remember, in that location is deviation betwixt fixed length listing returned from Arrays.asList() in addition to the 1 returned from Collections.unmodifiableList(). You cannot add or take away elements from the ArayList, but y'all tin alter the value at whatsoever index using set() inwards the illustration of one-time but non amongst the listing returned past times Collections.unmodifiableList() method.
This is the best method if y'all desire a minor list, but it becomes obscure in addition to less obvious if y'all need Set or other Collection, since 1 has to create a List earlier creating the Set, but it's yet ameliorate than double dyad initialization because it doesn't create anonymous inner classes every fourth dimension y'all piece of work it. See Core Java for Impatient for to a greater extent than details.
There is 1 to a greater extent than choice of double dyad initialization available, entirely if y'all are running inwards Java 8. The JDK 8 Stream API tin live used to create minor collections, past times combining current manufacturing works life methods in addition to collectors, every bit shown below:
If y'all desire a Set, y'all tin piece of work Collectors.toSet() method instead of Collectors.toList(), every bit seen inwards next illustration :
By the way, The streams collectors brand no guarantees most the mutability of collections they return. In Java 8, the returned collections are ordinary, mutable collections such every bit ArrayList, HashSet, in addition to HashMap, but this mightiness alter inwards hereafter JDK releases.
That's all most Double dyad initialization idiom inwards Java. It's ok for 1 of the uses, to a greater extent than oftentimes than non for testing in addition to demo, but it's non expert plenty to live used inwards production code. Due to its cons, Double dyad initialization has croak an antipattern nowadays, peculiarly amongst to a greater extent than suitable alternatives available. I yet piece of work double dyad initialization for initializing static maps, but that's it. For List in addition to Set, I prefer the combination of Arrays.asList() in addition to re-create constructor of Collection class. If I am running Java 8 thus I piece of work Stream API in addition to Collectors to produce the job.
Further Learning
article)Why is static code analysis of import for Java application? (article) 10 Best Practices to follow spell naming variables, shape in addition to methods inwards Java? (article) Must know multi-threading in addition to concurrency best practices for Java Programmers (article) Why y'all should non telephone holler upward System.exit() on Java Web Application? (answer) Why piece of work SLF4j over Log4j for logging inwards Java? (answer) 10 Articles Every Programmer must Read. (list) Why should y'all favor Composition over Inheritance inwards Java? (answer) Some Practical tips to avoid NullPointerException inwards Java? (answer) Why getter in addition to setter are ameliorate than populace fields inwards Java? (answer) Why use @Override notation inwards Java? (tip) How to write thread-safe code inwards Java? (tip) 10 best practices to follow spell commenting code (article)
List<Integer> listing = new ArrayList<>(); list.add(2); list.add(3); list.add(5); list.add(7); List<Integer> unmodifiableList = Collections.unmodifiableList(list);
This is quite verbose, in addition to because it cannot live expressed inwards a unmarried expression, static lists must live populated inwards static initializer blocks rather than via a to a greater extent than convenient plain initializer.
Double dyad initialization idiom tin produce this inwards only 1 draw every bit shown below:
List<Integer> listing = Collections.unmodifiableList(new ArrayList<Integer>() {{ add(2); add(3); add(5); }});
You tin likewise initialize HashMap amongst values using double dyad initialization every bit following:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{ put(1, "one"); put(2, "two"); put(3, "three"); }};
This looks pretty, but it has its ain laid of disadvantages, which made it an anti-pattern, we'll run into them inwards side past times side section.
Pros in addition to Cons of Double Brace Initialization inwards Java
Double dyad Initialization idiom internally it uses the instance initializer create inwards an anonymous inner class. Which agency it quite obscure, in addition to it costs an extra shape every fourth dimension y'all piece of work it. It likewise holds a hidden reference to the enclosing instance, which may motility retentiveness leaks. You cannot piece of work diamond operator in that location every bit good because it's non allowed to infer types inwards the anonymous class.Pros:
1) Less draw of code
2) Creation in addition to Initialization inwards the same expression
Cons:
2) Obscure, internally uses the instance initializer create of the anonymous class.
2) It terms an extra shape every fourth dimension y'all piece of work it
3) It holds a hidden reference to the enclosing instance, which may motility memory leaks.
Due to its disadvantage in addition to ameliorate choice double dyad initialization is straightaway considered every bit an anti-pattern inwards Java world.
Alternatives of Double Brace Initialization Idiom inwards Java
The Good matter is that y'all convey ameliorate alternatives to make the same consequence inwards Java e.g. y'all tin create in addition to initialize an ArrayList amongst values inwards 1 draw past times using Copy constructor from Collection class, every bit shown below :List<Integer> listing = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList() returns a fixed length list, which is passed to ArrayList re-create constructor. Remember, in that location is deviation betwixt fixed length listing returned from Arrays.asList() in addition to the 1 returned from Collections.unmodifiableList(). You cannot add or take away elements from the ArayList, but y'all tin alter the value at whatsoever index using set() inwards the illustration of one-time but non amongst the listing returned past times Collections.unmodifiableList() method.
This is the best method if y'all desire a minor list, but it becomes obscure in addition to less obvious if y'all need Set or other Collection, since 1 has to create a List earlier creating the Set, but it's yet ameliorate than double dyad initialization because it doesn't create anonymous inner classes every fourth dimension y'all piece of work it. See Core Java for Impatient for to a greater extent than details.
There is 1 to a greater extent than choice of double dyad initialization available, entirely if y'all are running inwards Java 8. The JDK 8 Stream API tin live used to create minor collections, past times combining current manufacturing works life methods in addition to collectors, every bit shown below:
List<String> listing = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
If y'all desire a Set, y'all tin piece of work Collectors.toSet() method instead of Collectors.toList(), every bit seen inwards next illustration :
Set<String> laid = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
By the way, The streams collectors brand no guarantees most the mutability of collections they return. In Java 8, the returned collections are ordinary, mutable collections such every bit ArrayList, HashSet, in addition to HashMap, but this mightiness alter inwards hereafter JDK releases.
That's all most Double dyad initialization idiom inwards Java. It's ok for 1 of the uses, to a greater extent than oftentimes than non for testing in addition to demo, but it's non expert plenty to live used inwards production code. Due to its cons, Double dyad initialization has croak an antipattern nowadays, peculiarly amongst to a greater extent than suitable alternatives available. I yet piece of work double dyad initialization for initializing static maps, but that's it. For List in addition to Set, I prefer the combination of Arrays.asList() in addition to re-create constructor of Collection class. If I am running Java 8 thus I piece of work Stream API in addition to Collectors to produce the job.
Further Learning
article)