1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Returning an array of generic type

  1. Apr 16, 2017 #1
    • Moved thread to homework forum
    This is a homework problem, so I have to follow some stipulations, namely:

    The problem is, I have no idea how to get a method to return a generic-type array. Because of type erasure, I can't create an instance T[] of a generic array, empty or otherwise.

    The only way I was able to do it was by setting the generic array reference variable to null. My first plan was to do that, then use an ArrayList of generic type to store the elements arr1 and arr2 have in common, and finally use the toArray() method to convert it into a "generic-type" array, which would be stored in the null-valued T[] reference variable, something like this:

    Code (Text):
    public static <T>
    T[] commonItems( T[] arr1, T[] arr2)
    {
          ArrayList<T> commonElements = new ArrayList<>();
          T[] commonItems = null;

          // Code for finding the common elements goes here

         return commonElements.toArray(commonItems);
    }
    The above code results in a NullPointerException being thrown (presumably because commonItems was initialized to null and not an array of any kind)

    Next I tried circumventing the "no generic array instantiation" rule by creating an array of type Object[] and casting it into a "generic type" array:

    Code (Text):

          ArrayList<T> commonElements = new ArrayList<>();
          T[] commonItems = (T[]) new Object[]{};

          // Code for finding the common elements goes here

         return commonElements.toArray(commonItems);
    Which results in a ClassCastException.

    I googled around and checked on Stack Overflow for a while about how to return generic-type arrays, and tried my own implementation of the closest thing I could find to a workaround, which basically involves writing a "conversion" method and using Array.newInstance() to make the generic array to be returned:

    Code (Java):
    public static <T>
        T[] commonItems(T[] arr1, T[] arr2)
        {
           
            // commonElements will store the elements
            // that occur in both arr1 and arr2
     
            ArrayList<T> commonElements = new ArrayList<>();
            T[] commonItems = null;
           
            // If one or both arr1 and arr2
            // are null, the output is the
            // null array
           
            if (arr1 == null || arr2 == null)
            {
                return commonItems;
            }
           
            // Nested enhanced for loops
            // used to iterate through the
            // two arrays
           
            for (T firstElement : arr1)
            {
                for (T secondElement : arr2)
                {
                    // If the two elements are
                    // equal, add it to
                    // commonElements
                   
                    if (firstElement.equals(secondElement))
                        commonElements.add(firstElement);
                }
            }
           
            // Return an array containing the
            // common items in arr1 and arr2
           
            return convertToArray(commonElements, arr1.getClass());
        }
       
        // HELPER METHOD FOR commonItems METHOD
       
        public static <T>
        T[] convertToArray(ArrayList<T> commonElements, Class<? extends Object[]> c)
        {
            // Use the newInstance() method to
            // instantiate an array, then cast
            // it to a generic type.
           
            T[] commonItems = (T[]) Array.newInstance(c, commonElements.size());
           
            // Now use the toArray() method
            // to convert commonElements
            // into an array of "generic"
            // type
           
            commonItems = commonElements.toArray(commonItems);
           
            // Return the array
           
            return (T[]) commonItems;
        }
    Which results in an ArrayStoreException at the line

    Code (Text):
    commonItems = commonElements.toArray(commonItems);
    I know that generic arrays (like T[]) would be converted to Object[] type arrays at runtime due to type erasure, but because of the method header (which I'm not allowed to change) the method won't run unless I return an array of type T[].

    I'm guessing the idea behind the method is for the "generic array" to be of the same type as arr1 and arr2, which was my reasoning for passing arr1.getClass() to the convertToArray method and trying to use it as an argument for the newInstance() method.

    But I don't know what else to try at this point.
     
  2. jcsd
  3. Apr 16, 2017 #2
    You created an array of arrays because your variable c was the class of T[] instead of the class of T.
    Anyway I think I got it to work. Try this.
    Code (Java):
    T[] commonItems(T[] arr1, T[] arr2)
    {
        ArrayList<T> commonElements = new ArrayList<>();
        T[] commonItems = null;

        if (arr1 == null || arr2 == null)
        {
            return commonItems;
        }

        for (T firstElement : arr1)
        {
            for (T secondElement : arr2)
            {
                if (firstElement.equals(secondElement))
                    commonElements.add(firstElement);
            }
        }

        if(commonElements.size() > 0) {
          commonItems = (T[]) Array.newInstance(commonElements.get(0).getClass(), commonElements.size());
          commonElements.toArray(commonItems);
        } else if(arr1.length > 0) {
          commonItems = (T[]) Array.newInstance(arr1[0].getClass(), 0);
        } else if(arr2.length > 0) {
          commonItems = (T[]) Array.newInstance(arr2[0].getClass(), 0);
        } else {
          commonItems = (T[])arr1.clone();
        }
        return commonItems;
    }
     
    Last edited: Apr 16, 2017
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Returning an array of generic type
  1. Array C++ (Replies: 2)

  2. C - array (Replies: 2)

  3. Function and array (Replies: 26)

Loading...