【问题标题】:ArrayLists better practiceArrayLists 更好的实践
【发布时间】:2020-04-20 13:18:56
【问题描述】:

我已经用 Java 编写了 2 个方法。第二种方法对我来说看起来更干净,因为我来自 python 背景,但我认为它会比第一种慢,因为 indexOf() 也进行迭代?在这种情况下,有没有办法正确使用 for in 循环?另外,如果有更好的方法(没有 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;
}

【问题讨论】:

  • 两者之间的差异可以忽略不计,我认为第二种方法更“昂贵”,因为您首先遍历数组,然后在满足特定条件时查找项目。使用适合您需要的for loop。如果您需要索引,请使用常规 for 循环(您的第一种方法)。
  • 是的,我说的慢是指更“贵”。有没有办法在 python 中做类似for i, myObject in enumerate(myObjects) 之类的事情,但使用 forIn 循环而不是标准 for 循环?

标签: java search arraylist


【解决方案1】:

我认为它会比第一个慢,因为 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 上,get(n)O(N))或者如果它不可实现(例如,如果您正在迭代 Stream),这将是一个很好的解决方案.

您也可以使用ListIterator 提供 myObjects 有一个返回ListIterator 的方法;有关示例,请参见 @Andy Turner 的 answer。 (它不适用于典型的 SetMap 类。)

【讨论】:

    【解决方案2】:

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

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

    您的第二种方法将处理LinkedLists 和ArrayLists,但它会在您的列表中迭代两次,一次在您的for 循环中,一次在indexOf() 调用中。

    我推荐第三个版本:使用第二种方法的 for 循环,并添加一个整数计数变量,在循环内递增。通过这种方式,您可以获得两全其美:在不降低性能的情况下进行迭代,以及廉价的位置计数。

    【讨论】:

      【解决方案3】:

      更好的方法是使用ListIterator

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

      【讨论】:

        猜你喜欢
        • 2013-03-11
        • 2012-01-10
        • 1970-01-01
        • 1970-01-01
        • 2010-12-19
        • 2020-07-20
        • 1970-01-01
        • 2018-02-09
        • 1970-01-01
        相关资源
        最近更新 更多