Java 转换列表的最快方法<&燃气轮机;列出<;ObjectType>;
这是一个Java问题 将Java 转换列表的最快方法<&燃气轮机;列出<;ObjectType>;,java,generics,optimization,list,Java,Generics,Optimization,List,这是一个Java问题 将列表转换为列表的最快方法是什么?我知道这是通过迭代实现的,请排除该选项 以迭代为例 final List<ObjectType> targetList = new ArrayList<ObjectType>(); // API returns List<?> so I have no choice. List<?> resultList = resultSet.getResults(); // This is slow.
列表
转换为列表
的最快方法是什么?我知道这是通过迭代实现的,请排除该选项
以迭代为例
final List<ObjectType> targetList = new ArrayList<ObjectType>();
// API returns List<?> so I have no choice.
List<?> resultList = resultSet.getResults();
// This is slow. Average list size is 500,000 elements.
while (resultList != null && !resultList.isEmpty()) {
for (final Object object : resultList) {
final ObjectType objectType = (ObjectType) object;
targetList.add(objectType);
}
resultSet = someService.getNext(resultSet);
resultList = resultSet.getList();
}
final List targetList=new ArrayList();
//API返回列表,所以我别无选择。
List resultList=resultSet.getResults();
//这太慢了。平均列表大小为500000个元素。
while(resultList!=null&&!resultList.isEmpty()){
for(最终对象:结果列表){
最终ObjectType ObjectType=(ObjectType)对象;
add(objectType);
}
resultSet=someService.getNext(resultSet);
resultList=resultSet.getList();
}
谢谢。嗯。。。如果你真的要处理500000个元素,并且表现出性能问题,我会咬紧牙关(子弹是编译器的“未检查”警告)并抛出它:
List<ObjectType> targetList = new ArrayList<ObjectType>((List<ObjectType>) resultList);
List targetList=new ArrayList((List)resultList);
然后可以使用@SuppressWarnings(“未选中”)注释来抑制警告
当然,以上假设
resultList
在某种程度上不能满足您的要求(可能是不可修改的,或者是支持数组的,或者是您所拥有的)。否则,你可以简单地施放它。这有点可怕,但根据上下文的不同,你可能不需要施放:
final List<ObjectType> targetList = (List<ObjectType>)problemSolver.getResults();
final List targetList=(List)problemSolver.getResults();
正确的解决方案取决于您是否希望确保放入targetList
的元素确实是ObjectType
的实例(或子类型)
如果你不在乎,其中一个带有不安全类型转换的解决方案就可以了。除非您需要复制,@Toms解决方案更好。(如果getResults()
返回一个链表,并且您的算法需要大量使用targetList.get(int)
,您可能需要进行复制。)但请注意,如果您的假设不正确,以后可能会出现意外的ClassCastException
如果需要确保没有错误类型的元素,则必须使用基于迭代器的解决方案,除非您知道getResults()
提供的List
类型。(如果您可以将getResults()
的结果强制转换为ArrayList
,那么使用get(int)
进行索引应该比使用迭代器
更快。另一方面,如果结果是链接列表
,则使用get(int)
复制列表是O(N**2)
)
这个怎么样
final List<?> resultList = problemSolver.getResults();
List<ObjectType> targetList;
if (resultList == null || resultList.isEmpty()) {
targetList = Collections.empyList();
} else {
int len = resultList.size();
// it is important to preallocate the ArrayList with the
// right size ... to conserve space and avoid copy on realloc
// of the list's private backing array.
targetList = new ArrayList<ObjectType>(len);
if (resultList instanceof ArrayList) {
// Copy using indexing - O(N) for ArrayLists
ArrayList<?> arrayList = (ArrayList) resultList;
for (int i = 0; i < len; i++) {
targetList.add((ObjectType) (arrayList.get(i)));
}
} else {
// Copy using iterator - O(N) for all sane List implementations,
// but with a larger C than the best case for indexing.
for (Object obj : resultList) {
targetList.add((ObjectType) obj);
}
}
}
final List resultList=problemSolver.getResults();
列出目标清单;
if(resultList==null | | resultList.isEmpty()){
targetList=Collections.empyList();
}否则{
int len=resultList.size();
//使用
//大小合适…以节省空间并避免在realloc上复制
//列表的专用支持数组的。
targetList=新阵列列表(len);
if(结果列表实例为ArrayList){
//对ArrayList使用索引-O(N)进行复制
ArrayList ArrayList=(ArrayList)结果列表;
对于(int i=0;i
迭代有什么问题
但如你所愿:
final List<?> src = ...;
final int len = src.size();
final SomeType[] dstArray = new SomeType[len];
src.<SomeType>toArray(dstArray);
final List<SomeType> dst = java.util.Arrays.asList(dstArray);
最终列表src=。。。;
final int len=src.size();
final SomeType[]dstArray=新SomeType[len];
src.toArray(DST阵列);
最终列表dst=java.util.Arrays.asList(dstArray);
或:
(免责声明:与其说是编译的,不如说是编译的。)
我更喜欢迭代法。正如Tom在上面所说的,如果您知道原始
列表中的所有内容都是对象类型
——正如迭代代码所暗示的那样——转换到列表
会很好
与迭代代码的唯一区别在于,如果任何东西不是对象类型
,则在迭代代码中,当您填充目标列表
时,将发生ClassCastException
,而使用直式转换时,将在您获取值时发生。例如:
public static void main(String[] args) {
List<?> list = Arrays.<Object> asList('I', "am", "not", "homogeneous");
List<Character> targetList = (List<Character>) list;
int index = 0;
try {
for (Character c : targetList) {
System.out.println(c);
index++;
}
} finally {
System.out.println("Reached " + index);
}
}
由于您使用的是基于数组的列表,您是否尝试过预分配500000个元素(或者大约为500000个)。这可能会提高性能。现在我想一想,LinkedList可以完全消除整个“预分配内存”问题。是否有什么东西可以从resultList
中删除元素,或者是而应该是if
?@Laurence Gonsalves,好问题,我已经修改了代码。谢谢。LinkedList
应该慢一点。你会不必要地使用大量内存。对于这个问题,我也会采用这种解决方案。一般来说,这不是类型安全的。我采用这种方法,尽管我将其隐藏在Lists.cast()实用程序方法后面,这样你实际上就不需要告诉RHS列表中有哪些类型(无论如何,大多数情况下)。嗯。。。src.toArray()不创建副本吗?是的,虽然这不应该是一个大问题(仍然比LinkedList
!)要好)。我忘记了带参数的toArray
有奇怪的界限。
I
Exception in thread "main" java.lang.ClassCastException: java.lang.String
cannot be cast to java.lang.Character
at Foo.main(Foo.java:100)
Reached 1