ArrayLists最佳实践

问题描述 投票:0回答:2

我已经用Java编写了2种方法。第二种方法对我来说看起来更干净,因为我来自python背景,但是我认为它会比第一种方法慢,因为indexOf()也可以进行迭代吗?有没有办法在这种情况下正确地用于循环?另外,如果有更好的方法(没有Streams),该怎么办?

private ArrayList<MyObject> myObjects;

第一种方法:

private int findObject(String objectName) {
    for(int i=0; i<this.myObjects.size(); i++) {
        MyObject myObject = this.myObjects.get(i);
        if(myObject.getName().equals(objectName)) return i;
    }
    return -1;
}

第二种方法:

private int findObject(String objectName) {
    for(MyObject myObject: this.myObjects) {
        if(myObject.getName().equals(objectName)) return this.myObjects.indexOf(myObject);
    }
    return -1;
}
java search arraylist
2个回答
0
投票

更好的方法(这样可以避免您必须维护单独的索引变量;并且也适用于非RandomAccess列表)将使用ListIterator

for (ListIterator<MyObject> it = myObjects.listIterator(); it.hasNext();) {
  MyObject myObject = it.next();
  if(myObject.getName().equals(objectName)) return it.prevIndex();
}
return -1;

0
投票

我认为它会比第一个慢,因为indexOf()也会进行迭代吗?

您是正确的。

在这种情况下是否可以正确使用for each循环?

您可以使用for each和索引变量。

private int findObject(String objectName) {
    int i = 0;
    for (MyObject myObject: this.myObjects) {
        if (myObject.getName().equals(objectName)) return i;
        i++;
    }
    return -1;
}

如果myObjects.get(i)是昂贵的操作(例如,在LinkedList中)...或无法实现,这将是一个很好的解决方案。


0
投票

第一个版本是完美的如果您知道您正在使用ArrayList(或其他一些基于数组的列表,例如Vector)。

如果myObject恰好是LinkedList或类似名称,则列表越长,性能就会越差,因为get(i)不再按固定时间执行。

您的第二种方法将同时处理LinkedListArrayList,但在列表上进行两次迭代,一次在for循环中,一次在indexOf()调用中。

我建议使用第三种版本:使用第二种方法中的for循环,并添加一个整数计数变量,并在循环内递增。这样,您将获得两者的优点:在不降低性能的情况下进行迭代以及廉价的头寸计数。

© www.soinside.com 2019 - 2024. All rights reserved.