0

So I have an ArrayList of Products that I instantiate at the beginning of my Category class...

    private ListInterface<Product> products;

    public Category(String categoryName) {
           products = new ArrayList<Product>();
    }

and I want to return a deep copy of all products of a specific category using the following method...

    public ListInterface<Product> getAllProducts() {
           ListInterface<Product> temp = new ArrayList<Product>();              
           for (Product prod : products.toArray()) // CAST EXCEPTION HERE
                temp.add(prod);
           return temp;
    } 

and here is the toArray() method...

    public E[] toArray() {
    @SuppressWarnings("unchecked")
    E[] result = (E[])new Object[size];

    for (int index = 0; index < size; index++) {
        result[index] = list[index];
    }

    return result;
    }

When running the program, I get "Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.O bject; cannot be cast to [L...Product;" in the 'for' loop of the getAllProducts() method.

I am confused as to why I am getting this exception as .toArray() should return a Product[]. Is there an easier way to deep copy and return this ArrayList?

noob4lyfe
  • 53
  • 4
  • 2
    What is a `ListInterface`? – azurefrog Nov 05 '19 at 23:06
  • 1
    Possible duplicate of [How to create a generic array in Java?](https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java) – Tom Nov 05 '19 at 23:07
  • 1
    The problem is the line `E[] result = (E[])new Object[size];`. You cannot cast arrays like this, any more than you can do `(String[]) new Object[] { "Hello", "world" }`. An `Object[]` is not a `Product[]`, even if the objects in the array are all `Product` instances, so the cast fails. – kaya3 Nov 05 '19 at 23:10
  • @azurefrog its an interface for the ADT list. – noob4lyfe Nov 05 '19 at 23:14
  • @kaya3 unfortunately that line of code is not mine (that's my professor's code). is there another way to copy the ArrayList without the toArray() method that is not overly complex? – noob4lyfe Nov 05 '19 at 23:16
  • @noob4lyfe The easiest way is just to iterate over the original list and clone() each element. See https://stackoverflow.com/questions/715650/how-to-clone-arraylist-and-also-clone-its-contents – azurefrog Nov 05 '19 at 23:19
  • I suggest raising the issue with your professor, then. @azurefrog, this is a custom list class implementing a custom list interface; I suspect it does not implement `Iterable`, so that's not going to be possible. – kaya3 Nov 05 '19 at 23:20
  • @kaya3 Even if the interface doesn't support iteration, the OP's example toArray() method makes it look like direct access to the backing array (`list`) is possible. – azurefrog Nov 05 '19 at 23:22

1 Answers1

0

Well,the ArrayList implements the Cloneable interface. So, one good thing you could do is start reading codes of the standard libs. I extracted this specific method:

    /**
     * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
     * elements themselves are not copied.)
     *
     * @return a clone of this <tt>ArrayList</tt> instance
     */
    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

I recommend you to always try to learn from it. And I hope it helps.

Fabiano
  • 1,044
  • 5
  • 20