4

I have been trying to access the elements of several arrays that are held within an array list. I am able to access it regularly, but the problem comes when I use generic type E to account for different data types. This gives me a class cast exception. If I change the type of tempStart and tempScan and corresponding casts to int[] (since that is what I am using to pass in) it runs.

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
    if (list.get(0).getClass().isArray()) {
        System.out.println(" I am an array!");
        //go through the arrays and make sure they are 
        //not the same, remove any that are the same
        //make flag to see if something is different
        boolean matching;
        for (int idx = 0; idx < list.size() - 1; idx++) {
            E[] tempStart =(E[])list.get(idx);
            for (int k = idx + 1; k < list.size(); k++) {
                matching = true;
                E[] tempScan = (E[])list.get(k);
                for (int index = 0; index < tempStart.length; index++) {
                    if (tempStart[index] != tempScan[index]) {
                        matching = false;
                    }
                }
                if (matching) {
                    list.remove(tempScan);
                    k--;
                }
            }
        }
cashew
  • 43
  • 2
  • Your for loops are iterating over list.size. Are you checking to see if two arrays in the arraylist are the same, or if elements within the arrays held by the arraylist are the same? – lmcphers Jun 19 '15 at 21:45

1 Answers1

4

You are trying to cast E to E[] and it's obviously not correct. Try something like:

import java.lang.reflect.Array
...
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
    ArrayList<E> retList = new ArrayList<>(list.size());
    if (list.isEmpty()) return retList;
    if (list.get(0).getClass().isArray()) {
        boolean matching;
        for (int idx = 0; idx < list.size() - 1; ++idx) {
            E tempStart = list.get(idx);
            for (int k = idx + 1; k < list.size(); k++) {
                matching = true;
                E tempScan = list.get(k);
                int tempStartLen = Array.getLength(tempStart);
                for (int index = 0; index < tempStartLen; index++) {
                    if (Array.get(tempScan, index) != Array.get(tempStart, index)) {
                        matching = false;
                    }
                }
                if (matching) {
                    list.remove(tempScan);
                    k--;
                }
            }
        }
        return retList;
    } else {
        throw new IllegalArgumentException("List element type expected to be an array");
    }
}

However because we are using Java Reflection Array to manipulate the array operation, using generic E doesn't make sense here. You can simple declare it as ArrayList<Object>

Updates: as @afsantos comments below, the parameter type ArrayList could be declared as ArrayList<?> as nothing is going to be insert into it.

Gelin Luo
  • 13,399
  • 23
  • 77
  • 119
  • The `list` parameter of the method could use wildcards, since no elements are inserted into it: `ArrayList> list`. – afsantos Jun 19 '15 at 21:50
  • That worked! I am working on a school assignment that requires us working with generic types, so that is why I was in that weird situation. Thank you! – cashew Jun 19 '15 at 22:16
  • 1
    Keep in mind the solution is **NOT** a way of working with generic types at all. Actually using generic with array is never a good idea. See http://stackoverflow.com/questions/1817524/generic-arrays-in-java – Gelin Luo Jun 20 '15 at 00:35