ZNackasha
ZNackasha

Reputation: 1089

Casting generic array

I'm trying to create a generic Intersection function that receives two arrays, the function would return an array with the commonality. The following is an example using what I currently have.

public static <T> T[] Intersection(T[] v1, T[] v2) {
    HashSet<T> set = new HashSet<>();
    set.addAll(Arrays.asList(v1));
    set.retainAll(Arrays.asList(v2));

    T[] v3 = {};
    v3 = set.toArray(v3);
    return v3;
}

My issue with the code above is: T[] v3 = {} results in the following error Cannot create a generic array of T . If I change the code to the following I get a warning stating Type safety: Unchecked cast from Object[] to T[].

public static <T> T[] Intersection(T[] v1, T[] v2) {
    HashSet<T> set = new HashSet<>();
    set.addAll(Arrays.asList(v1));
    set.retainAll(Arrays.asList(v2));

    T[] v3 = (T[])set.toArray();
    return v3;
}

Is there a safe way to accomplish this?

Upvotes: 0

Views: 92

Answers (2)

null
null

Reputation: 11839

You can use Arrays.copyOf with 0 length to construct an array copying a type from another array.

public static <T> T[] Intersection(T[] v1, T[] v2) {
    HashSet<T> set = new HashSet<>(Arrays.asList(v1));
    set.retainAll(Arrays.asList(v2));
    return set.toArray(Arrays.copyOf(v1, 0));
}

Note that in general, you are better of not using generics with arrays, instead preferring Lists. Arrays interact really badly with generics. You can use Arrays.asList to create a List interface view for an array if you have an array.

public static <T> List<T> Intersection(Collection<? extends T> v1, Collection<? extends T> v2) {
    ArrayList<T> newList = new ArrayList<>(v1);
    newList.retainAll(new HashSet<>(v2));
    return newList;
}

Upvotes: 2

Yury Nevinitsin
Yury Nevinitsin

Reputation: 158

Arrays in java not castable in general. That is why all collections have 2 toArray methods: Object [] toArray () and <T> T[] toArray (T[] array). If you cant know the array type at runtime, you have to deal with Object[]. In your case you have v1 and v2 of the desired type, and thus can use Arrays.copyOf and typed toArray.

T[] v3 = set.toArray(Arrays.copyOf(v1, set.size()));

Upvotes: 2

Related Questions