How to avoid a generics warning
I have a utility function that will shuffle t开发者_如何学运维he elements of any Vector, but which generates generic warnings about using raw types.
static public void shuffle(Random r,Vector v)
{ int sz = v.size();
for(int pass = 0;pass<4;pass++)
{ for(int i=0;i<sz;i++)
{ int j=nextInt(r,sz);
Object ii = v.elementAt(i);
v.setElementAt(v.elementAt(j),i);
v.setElementAt(ii,j);
}
}
}
there seems to be no way to quiet the warnings other than by
suppressing them. Changing the method signature to Vector<Object>
restricts the callers Vector<Object>
. Changing to Vector<?>
makes
the setElementAt uncompilable.
First you should note that you're reinventing the wheel.
Collections.shuffle
(yourVector, yourRandom);
does the trick :-)
To make your method generic for all types of Vector
s, this is the way to write it:
static public <T> void shuffle(Random r, Vector<T> v) {
int sz = v.size();
for (int pass = 0; pass < 4; pass++) {
for (int i = 0; i < sz; i++) {
int j = nextInt(r, sz);
T ii = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(ii, j);
}
}
},
As pointed out already, you can do this with generics like so:
public static <T> void privateShuffle(Random r, Vector<T> v) {
int sz = v.size();
for (int pass = 0; pass < 4; pass++) {
for (int i = 0; i < sz; i++) {
int j=nextInt(r,sz);
T ii = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(ii, j);
}
}
}
However, since you're writing a utility method I'd prefer the ?
wildcard syntax - it's a lot cleaner to look at. As you've already noted, you can't use the following header directly on that method, but I'd be tempted to do something like the following:
public static void shuffle(Random r, Vector<?> v) {
privateShuffle(r, v);
}
private static <T> void privateShuffle(Random r, Vector<T> v) {
int sz = v.size();
for (int pass = 0; pass < 4; pass++) {
for (int i = 0; i < sz; i++) {
int j=nextInt(r,sz);
T ii = v.elementAt(i);
v.setElementAt(v.elementAt(j), i);
v.setElementAt(ii, j);
}
}
}
Yes, it's an extra method, but that way you get to expose the "clean API" look of the unbounded wildcard whilst still maintaining the type safety (this is how a lot of the Java API methods work.)
As a side note, I'd also re-iterate that unless you're doing this for legacy reasons, Vector is generally considered an obsolete collection these days and a much better choice would be to use a list (and code to the list interface.)
You could use the supresswarning annotation
@SuppressWarnings("unchecked")
edit: why doesn't the vector < T > work for you? It should? :)
精彩评论