简体   繁体   中英

How to avoid a generics warning

I have a utility function that will shuffle the 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? :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM