3 ms·
It was wrong.
by Communitivity 4y ago
It was wrong.
- tsimionescu 4y ago> Another way to write the constructor, that works in current Java, might be to use the Streams API to make sure we are coding to the explicit and implicit design contracts: public FilteredSet(Predicate<? super E> filter, Collection<? extends E> elems) { super(checkElems(elems).stream() .filter(filter) .collect(Collectors.toList()); this.filter = filter; } I think you misunderstood the problem. Assuming you leave the add() method implemented exactly as in the JEP, this will still fail with the same NullPointerException, since super() will still call FilteredSet.add() before this.filter is provided. The only way to avoid it without this JEP is to do something like this: public FilteredSet(Predicate<? super E> filter, Collection<? extends E> elems) { super(elems.size()); //initialize super as an empty HashSet, but with the proper capacity this.filter = filter; this.addAll(elems); //this will call this.add(), but this.filter will now be set } Your description of the contract/purpose of HashSet.add() is also just wrong. The clear intention of the Java standard library designers is that any element added to the set, either by the constructor or later, is added using HashSet.add() - they are explicitly calling that method from the built-in HashSet constructor [0]. Also, it's an obvious design choice, while your proposal is just weird: why would you ever want to duplicate the implementation of adding elements between initialization and later modification? In general, you seem to be arguing for keeping the language more clunky. Why does `7 instanceof int` or `switch(number)` or avoiding a new method definition just to check a variable before calling a constructor hurt the identity of Java in any way? Sure, all of these things could be achieved in various ways before as well, but always in a more clunky way. Many of these JEPs are pure cleanup of bizarre idiosyncrasies of Java - the precise opposite of how C++ is evolving. [0] https://github.com/openjdk/shenandoah/blob/master/src/java.base/share/classes/java/util/HashSet.java https://github.com/openjdk/shenandoah/blob/master/src/java.b... - note that the doc is not very explicit, but it does say that `c` is "the collection whose elements are to be placed into this set", not something like "the collection whose elements will be used to initialize this set".