开发者

How to avoid a generics warning

开发者 https://www.devze.com 2023-02-13 01:41 出处:网络
I have a utility function that will shuffle t开发者_如何学运维he elements of any Vector, but which generates generic

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 Vectors, 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? :)

0

精彩评论

暂无评论...
验证码 换一张
取 消