Reputation: 1089
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
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 List
s. 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
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