Returning an array of generic type

In summary, the commonItems method takes in two arrays and returns an array that contains the items that occur in both arrays. It uses an ArrayList to store the common elements and then converts it into a generic-type array using the convertToArray helper method. The method also accounts for edge cases such as null arrays and empty arrays. The key to getting it to work is passing in the class of the elements in the commonElements ArrayList to the Array.newInstance() method.
  • #1
Enharmonics
29
2
Moved thread to homework forum
This is a homework problem, so I have to follow some stipulations, namely:

Do not change the method header in any way.
Do not use the classes Arrays, Collections, Set, or Map.
You can use the java.lang.reflect.Array class. Use equals to
test if two items are equal.

The method

Java:
public static <T>
T[] commonItems( T[] arr1, T[] arr2)

returns an array that contains the items that occur in both array1 and array2. Assume that the 2 arrays have no duplicate items. If one or both arrays are null, the output is the null array. If the 2 arrays have no atoms in common, commonItems returns the empty array.

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:
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:
      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:

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:
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.
 
Physics news on Phys.org
  • #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.
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:

What is an array of generic type?

An array of generic type is an array that can hold elements of any type. This means that the type of the elements in the array can be determined at runtime, instead of being fixed at compile time like in a regular array.

Why would I want to return an array of generic type?

Returning an array of generic type allows for more flexibility in the code. It allows the method to be used with different types of data without having to create multiple methods for each type. This can save time and reduce code redundancy.

How do I declare and use an array of generic type?

To declare an array of generic type, you can use the syntax "T[] arrayName = new T[size];", where T is the generic type and "size" is the size of the array. To use the array, you can access elements using their index, just like in a regular array.

What are the limitations of using an array of generic type?

One limitation is that you cannot use primitive types (such as int or double) as the generic type. Another limitation is that the type of the elements must be consistent within the array, so you cannot have a mix of different types.

Can I pass an array of generic type as a parameter to a method?

Yes, you can pass an array of generic type as a parameter to a method. However, you will need to specify the type when calling the method, as the type cannot be inferred from the array itself.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
18
Views
1K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
4
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
  • Programming and Computer Science
Replies
3
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
6
Views
3K
  • Programming and Computer Science
Replies
6
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
Back
Top