0

I am implementing an ordered list that automatically inserts elements in the correct sorted position using a Comparator. The list is built from scratch (not using java.util.ArrayList) and uses an internal raw array.

Here is the base list implementation:

public class ArrayList<T> implements ListADT<T> {
    protected T[] array;
    protected int count;
    private static final int DEFAULT_CAPACITY = 10;

    @SuppressWarnings("unchecked")
    public ArrayList() {
        array = (T[]) (new Object[DEFAULT_CAPACITY]); // internal storage
        count = 0;
    }

    protected void expandCapacity() {
        array = java.util.Arrays.copyOf(array, array.length * 2);
    }
}

And here is the ordered version:


public class ArrayOrderedList<T> extends ArrayList<T> implements OrderedListADT<T> {

    private Comparator<T> comparator;

    public ArrayOrderedList(Comparator<T> comparator) {
        this.comparator = comparator;
    }

    @Override
    public void add(T element) {
        if (count == array.length)
            expandCapacity();

        int i = 0;

        // The error occurs here:
        while (i < count && comparator.compare(element, array[i]) > 0) {
            i++;
        }

        for (int j = count; j > i; j--) {
            array[j] = array[j - 1];
        }

        array[i] = element;
        count++;
    }
}

public interface OrderedListADT<T> extends ListADT<T> {

public void add(T element);

}
public interface ListADT<T>  extends Iterable<T>{

    public T removeFirst();

    public T removeLast();

    public T remove( T Object);
    public T first();

    public T last();

    public boolean contains(T target);

    public boolean isEmpty();

    public int size();

    public Iterator<T> iterator();

    public String toString();


}

Demo code:

public class ArrayOrderedListDemo {
    public static void main(String[] args) {
        ArrayOrderedList<Integer> array1 = new ArrayOrderedList<>(Comparator.naturalOrder());
        array1.add(2);
        array1.add(5);
        array1.add(4);
        array1.add(1);
    }
}



Expected behavior

I expect the elements to be inserted in sorted ascending order, for example:

[1, 2, 4, 5]

Actual Runtime Error

Exception in thread "main" java.lang.ClassCastException:
class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Comparable;
([Ljava.lang.Object; and [Ljava.lang.Comparable; are in module java.base of loader 'bootstrap')
    at OrderedList.ArrayOrderedList.add(ArrayOrderedList.java:14)
    at OrderedList.ArrayOrderedListDemo.main(ArrayOrderedListDemo.java:10)

What I understand so far

This happens because the internal array is actually an Object[] but the comparison operation indirectly expects the stored elements to be in a Comparable[] (even though I am using a Comparator).

Constraints

This is an academic exercise where:

The list must be implemented from scratch.

I cannot use java.util.ArrayList.

I cannot use reflection or Array.newInstance(...).

I must store elements in a generic array like this:

array = (T[]) new Object[n];

My Question

How can I safely compare elements using a Comparator when they are stored in an Object[], without converting the internal array into a Comparable[], and without using reflection?

20
  • 1
    Please show a minimal reproducible example demonstrating the ClassCastException. Commented Nov 5 at 11:32
  • 3
    The code you showed does not compile. Even if we ignore undeclared things like ListADT and expandCapacity, and assume you meant to say new ArrayOrderedList<>(Integer::compare); in your main method, there are still no exceptions when I run the code. Commented Nov 5 at 11:52
  • 1
    @Raam Sweeper does not get the exception because the posted code does not compile and he is forced to make assumptions to make it runnable. Same for me by the way, no exception after assumptions to compile and run. Commented Nov 5 at 12:41
  • 1
    At a minimum we need the actual definitions of OrderedListADT and ListADT that you're using, plus what your main method actually looks like (As stated it will throw generics-related compiler errors with the passed comparator). Commented Nov 5 at 12:59
  • 2
    The code you’ve shown does not match the exception. The exception indicates that you used something like ArrayOrderedList<T extends Comparable> instead of ArrayOrderedList<T>. If you changed that at some point of time, you haven’t recompiled your code since then. Commented Nov 6 at 10:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.