Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何";勾选“;演员阵容?_Java_Generics_Dictionary_Android Studio_Casting - Fatal编程技术网

Java 如何";勾选“;演员阵容?

Java 如何";勾选“;演员阵容?,java,generics,dictionary,android-studio,casting,Java,Generics,Dictionary,Android Studio,Casting,我编写了一个从映射中获取随机值的方法。我首先得到了地图中的所有值,然后使用Random对象得到一个随机值。方法如下: public static <K, V> V getRandomValInMap (Map<K, V> map) { Collection<V> values = map.values (); V[] array = (V[])values.toArray (); return array[random.nextInt

我编写了一个从
映射中获取随机值的方法。我首先得到了地图中的所有值,然后使用
Random
对象得到一个随机值。方法如下:

public static <K, V> V getRandomValInMap (Map<K, V> map) {
    Collection<V> values = map.values ();
    V[] array = (V[])values.toArray ();
    return array[random.nextInt (array.length)];
}
Android Studio表示,它是“从
Object[]
V[]
的未经检查的强制转换”。所以我想这有点“冒险”。我尝试使用另一个超载的
来排列

V[] array = new V[values.size()];
array = values.toArray (array);
我猜这不是使用重载的方式,因为有一个编译器错误说我不能初始化
V

所以我想也许我应该使用第一种方法。但我如何“检查”演员阵容以取消警告


或者,您可以告诉我如何正确使用
toArray(T[]数组)
重载。

您无法创建泛型类型的数组,这是Java中的一个已知限制,对此有充分的理由。所以这是不可能的:
V[]数组=新的V[values.size()]

另见:


您可以在运行时使用
instanceof
对其进行检查,但如果您知道,只有正确类型的对象才会出现在映射中,则应该保持原样-修复带有不必要运行时开销的警告是个坏主意。此警告基本上意味着,无法确保始终从地图中获取正确的对象

由于类型擦除,
new V
无法工作。在Java中,当引入泛型时,这是一个保持向后兼容性的设计决策

如果您只关心警告,当然可以抑制它。

Java中有一个警告,编译时泛型类型将被删除,并将其作为
对象处理

您可以通过以下方式抑制警告:

public static <K, V> V getRandomValInMap (Map<K, V> map) {
    Collection<V> values = map.values ();
    @SuppressWarnings("unchecked") V[] array = (V[])values.toArray ();
    return array[1];
}
publicstaticvgetrandomValinMap(映射映射){
集合值=map.values();
@SuppressWarnings(“未选中”)V[]数组=(V[])values.toArray();
返回数组[1];
}

引用Bruce Eckel在Java Thinking in Java usingArray.newInstance中的话,这是在泛型中创建数组的推荐方法

公共类数组生成器{
私人类;
公共数组生成器(类种类){this.kind=kind;}
@抑制警告(“未选中”)
T[]创建(整数大小){
return(T[])数组.newInstance(种类、大小);
}
}

您可以使用此方法并从地图的键和值填充数组。

更好的做法是根本不创建新数组:

public static <K, V> V getRandomValInMap (Map<K, V> map) {
    Collection<V> values = map.values ();

    Iterator<V> it = values.iterator();
    int choosen = new Random().nextInt (values.size());
    for (int i=0; i<values.size();i++) {
        V value = it.next();
        if (i==choosen) return value;
    }
    throw new AssertionError("Choosen value out of bounds");
}
publicstaticvgetrandomValinMap(映射映射){
集合值=map.values();
迭代器it=values.Iterator();
int choosen=new Random().nextInt(values.size());

对于(inti=0;iHmm),我喜欢你的想法。让我试试。
public class ArrayMaker<T> { 
 private Class<T> kind; 
 public ArrayMaker(Class<T> kind) { this.kind = kind; } 
 @SuppressWarnings("unchecked") 
 T[] create(int size) { 
  return (T[])Array.newInstance(kind, size); 
 }
}
public static <K, V> V getRandomValInMap (Map<K, V> map) {
    Collection<V> values = map.values ();

    Iterator<V> it = values.iterator();
    int choosen = new Random().nextInt (values.size());
    for (int i=0; i<values.size();i++) {
        V value = it.next();
        if (i==choosen) return value;
    }
    throw new AssertionError("Choosen value out of bounds");
}