只访问一次Java中泛型List的每个元素

时间:2016-02-05 14:20:03

标签: java list listiterator

我在Java中有一个List,我想只访问每一个元素一次。例如,如果我有一个数组,我会做类似的事情:

O[] x = ...;
for(int i = 0; i<x.length; i++){
     for(int j=i+1; j<x.length;j++){
          someOperation(x[i],x[j]);
     }
}

问题是我有一个List(我们假设不知道List是ArrayList还是LinkedList)。 为了具有与之前列出的情况相同的复杂性,我将使用伪代码编写,例如:

 ListIterator<O> it1 = list.listIterator();
 while(it1.hasNext()){
      O x = it1.next();
      it2 = it1.clone();   //it2 have the same "status" of it1, but it is a different object in memory
      while(it2.hasNext()){
           y= it.next();
           someOperation(x,y);
      }
 }

据我所知,我们没有像it1.clone()这样的东西。做或多或少做类似事情的唯一方法是:

 int i = it1.nextIndex();
 it2 = list.listIterator(i);

但据我所知,

 list.listIterator(i);

可能具有O(n)的复杂性 - 在LinkedList的情况下,这在其他语言中是绝对可以避免的。另一方面,使用随机访问(如list.get(i))实现相同的算法甚至会更糟。 假设列表是LinkedList,编写代码的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

如果您可以修改列表:

Iterator<Items> things = list.iterator();

while(things.hasNext()){
    Item item = things.next();
    things.remove();
    Iterator<Item> others = list.iterator();
    while(others.hasNext()){
        //... do stuff;
    }
}

如果订单无关紧要,您可以建立一个新的列表。

List<Item> others = new ArrayList<>(list.size());
for(Item item: list){
    for(Item other: others){
        // do stuff
    }
    others.add(item);
}

答案 1 :(得分:1)

我认为最好的解决方案是使用list.listIterator(i)

在LinkedList的情况下,这是O(n),但算法的复杂性仍然是O(n ^ 2)。就Big-Oh而言,它不会改变任何东西!

干杯

答案 2 :(得分:1)

你不能只交换ij吗?

List<E> x = ...;
int j = 0;
for (E ej : x) {
    int iMax = j++;
    int i = 0;
    for (E ei : x) {
        if (i++ >= iMax)
            break;
        someOperation(ei, ej);
    }
}