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");
}