0

I know it is possible to override the .add behaviour of ArrayList, but how can it be? Where is it defined in the Java docs? What does it mean to have curly braces {} after the generic definition ?

List<Element> SortedListOfElements = new ArrayList<Element>() {
    public boolean add(Element mt) {
        int index = Collections.binarySearch(this, mt);
        if (index < 0) {
            index = ~index;
        }
        super.add(index, mt);
        return true;
    }
};
Nathan B
  • 1,625
  • 1
  • 17
  • 15

1 Answers1

1

Where is it defined in the Java docs? What does it mean to have curly braces {} after the generic definition?

This is called anonymous class, you may need to check this tutorial page, such classes do not have specific names in the code, they are used to instantiate interfaces/abstract classes, or modify some known methods as in your case with List::add. The curly braces after the constructor are meant to define a class with some overridden/implemented methods.

Declaration of anonymous classes is described in JLS 15.9.5.


Your solution seems to be almost fine with a few comments:

  • if Collections::binarySearch is applied to instances of Segment class, this class has to implement Comparable<Segment> interface
  • method List::addAll(Collection<? extends T> collection) should be overridden too, because default implementation just appends the elements of collection.
  • similarly, a constructor accepting a collection, may need to be overridden.

Thus it would be worth to provide a generic implementation of a "sorted" list instead of the anonymous class:

public class SortedArrayList<T extends Comparable<T>> extends ArrayList<T> {

    public SortedArrayList() {}

    public SortedArrayList(Collection<? extends T> collection) {
        super(collection);
        this.sort(Comparator.naturalOrder());
    }

    @Override
    public boolean add(T item) {
        int index = Collections.binarySearch(this, item);
        if (index < 0) {
            index = ~index;
        }
        super.add(index, item);
        return true;
    }

    @Override
    public boolean addAll(Collection<? extends T> collection) {
        for (T item : collection) {
            this.add(item);
        }
        return true;
    }
}

Usage:

List<Element> sortedList = new SortedArrayList<>();
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
  • My question is where in the javadocs it says I can put a custom function in a curly braces after the new ArrayList()? What part of the Java syntax is that? – Nathan B Feb 21 '22 at 11:37
  • 1
    This is called anonymous class, you may need to check [this tutorial page](https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html), such classes do not have specific names in the code, they are used to instantiate interfaces/abstract classes, or modify some known methods as in your case with `List::add`. Declaration of anonymous classes is described in [JLS 15.9.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9.5) – Nowhere Man Feb 21 '22 at 14:28
  • Thanks. Better to use @Override before the function, this what made me confuse. – Nathan B Feb 22 '22 at 13:45