Java如何:使用泛型从类创建泛型数组?
我有一个类Java如何:使用泛型从类创建泛型数组?,java,generics,Java,Generics,我有一个类FirstClass和一个类SecondClass,我想在从FirstClass调用的例程中创建一个O[],其中O是一个通用类参数。我不知道该怎么做 我特别需要一个O[](而不是ArrayList或类似的),因为我需要在循环体中经常从它获取元素,这对算法的执行时间很重要 所以我想要一些类似的东西 public class FirstClass<O> { void someRoutine(n and other params) { //Do some
FirstClass
和一个类SecondClass
,我想在从FirstClass
调用的例程中创建一个O[],其中O是一个通用类参数。我不知道该怎么做
我特别需要一个O[](而不是ArrayList
或类似的),因为我需要在循环体中经常从它获取元素,这对算法的执行时间很重要
所以我想要一些类似的东西
public class FirstClass<O> {
void someRoutine(n and other params) {
//Do some stuff
SecondClass<O> = new SecondClass(n, possibly_other_params);
//Do some stuff
}
}
公共类第一类{
void someRoutine(n和其他参数){
//做点什么
SecondClass=新的SecondClass(n,可能是其他参数);
//做点什么
}
}
及
公共类第二类{
O[]myArray;
第二类(整数n,可能是其他参数){
//这里是创建O[n]的构造函数
}
}
我在网上找到了一些方法,但不适用于我的案例:
- 使用
O[]数组=(O[])新对象[n]代码>但这不会编译
- 使用
Object[]数组=新对象[n]每次我请求数组中的内容时,都执行(O)强制转换,但这太慢了
- 使用
Array.newInstance(类类型,intn)代码>,带有
O代码>和
但它抱怨type=o.class
现在是type
类型,而不是class
,不管CAP#1是什么意思class
我应该如何在考虑最佳执行速度的情况下在Java中正确执行此操作?重复我在上面的评论,希望将此问题标记为已回答:
你真的分析过这个吗?演员阵容是否真的引起了你对表演的担忧?考虑到Java中的泛型在运行时会被删除,我认为要让它像您所期望的那样工作并不容易。我认为您最好尝试重新访问预期的API,然后尝试让Java的泛型以您想要的方式工作。以下是for
ArrayList.set
:
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
当然,它会进行额外的查找来获取旧元素,您并不关心它,但这是我们讨论的随机访问(读:O(1)次)。只需使用
ArrayList
,除非你有很难的数字显示它正在减慢你的速度。Java对泛型的处理非常粗糙,但是如果你准备进行一些小的调整,你可以完成一些接近你想要的事情。请参阅:
public class FirstClass<O> {
Class<O> type;
public static <O> FirstClass<O> create(Class<O> type) {
return new FirstClass<O>(type);
}
public FirstClass(Class<O> type) {
this.type = type;
}
public void routine(int size /*, other params */ ) {
SecondClass<O> instance = new SecondClass<O>(type, size);
}
}
public class SecondClass<O> {
public O[] array;
@SuppressWarnings("unchecked")
public SecondClass(Class<O> type,int size) {
array = (O[])Array.newInstance(type,size);
}
}
公共类第一类{
班级类型;
公共静态第一类创建(类类型){
返回新的头等舱(类型);
}
公共头等舱(类类型){
this.type=type;
}
公共无效例程(int size/*,其他参数*/){
SecondClass实例=新的SecondClass(类型、大小);
}
}
公务舱二等舱{
公共O[]数组;
@抑制警告(“未选中”)
公共第二类(类类型,整数大小){
array=(O[])array.newInstance(类型、大小);
}
}
以及一个用例:
FirstClass<Integer> instance = FirstClass.create(Integer.class);
instance.routine(110);
FirstClass实例=FirstClass.create(Integer.class);
例.例行(110);
这只是一个粗略的例子,尽管我相信您不必使用这种方法也可以完成类似的事情
使用O[]数组=(O[])新对象[n];但这需要一个(O)造型
每次我从数组中请求一些东西,所以这太慢了
什么?类型
O[]
的全部要点是,当您从中获取内容时,您不需要使用(O)
强制转换您实际分析过这一点吗?演员阵容是否真的引起了你对表演的担忧?考虑到Java中的泛型在运行时会被删除,我认为要让它像您所期望的那样工作并不容易。我认为您最好尝试重新访问预期的API,然后尝试让Java的泛型按您想要的方式工作。只需使用ArrayList
,sheesh。ArrayList的问题是我需要不断更改数组中的一个元素,这基本上就是这个内部循环所做的,因此是算法中最昂贵的部分。反复做a[i]=a[j]
来获得某种排列比一直做list.set(i,list.get(j))
要便宜得多。放置一个固定的数组类型确实会使它更快,但是我需要为25种可能的类型O-can中的每一种进行复制粘贴代码,这不是很好的风格。:/如果不可能,那当然不可能。无论如何,感谢您的输入。我为您创建了一个简化版的算法,带有适当的时间测量:您可以在您的计算机上验证,对于此算法使用None[]
和ArrayList
之间总是有一个系数4的差异。@user1111929好吧,我不能反驳这一点。试试Jordan White的解决方案——假设数组本身的创建非常罕见,那么这应该是可行的。我看不到一种直接的方法来测试它,但是出于好奇,为什么在他的解决方案中创建数组要比创建ArrayList更贵呢?这不是以几乎相同的方式在内部创建一个新的O[]吗?Array.newInstance
使用反射/本机魔法创建动态类型的数组,使它稍微慢一点。但是,即使对于您的需求来说,这种差异也可能可以忽略不计。实际上,您的基准测试有明显的缺陷,没有留出时间让JIT热身或做任何事情。我不相信它的结果是准确的。尝试使用这样一个工具,它知道如何用Java进行适当的基准测试。我为您创建了一个简化版的算法,带有适当的时间测量:正如您可以在计算机上验证的那样,转换会导致35%-50%的延迟。这不是小事。在我更为复杂的最终版本中,只有15-20%的延迟,但如果有其他选择,这也不是什么可以忘记的事情。事实上,你的
FirstClass<Integer> instance = FirstClass.create(Integer.class);
instance.routine(110);