在Java中,只访问泛型列表中的每两个元素一次

在Java中,只访问泛型列表中的每两个元素一次,java,list,listiterator,Java,List,Listiterator,我在Java中有一个列表,我想利用每两个元素只访问一次。例如,如果我有一个数组,我会这样做: O[] x = ...; for(int i = 0; i<x.length; i++){ for(int j=i+1; j<x.length;j++){ someOperation(x[i],x[j]); } } ListIterator<O> it1 = list.listIterator(); while(it1.hasNext

我在Java中有一个列表,我想利用每两个元素只访问一次。例如,如果我有一个数组,我会这样做:

O[] x = ...;
for(int i = 0; i<x.length; i++){
     for(int j=i+1; j<x.length;j++){
          someOperation(x[i],x[j]);
     }
}
 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);
      }
 }
但是,据我所知

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

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

对于LinkedList,这是O(n),但算法的复杂度仍然是O(n^2)。在大的方面哦,它不会改变任何事情


干杯

无论如何,我相信最好的解决方案是使用
list.listIterator(I)

对于LinkedList,这是O(n),但算法的复杂度仍然是O(n^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;
    }
}
Iterator things=list.Iterator();
while(things.hasNext()){
Item=things.next();
事物。移除();
Iterator others=list.Iterator();
while(others.hasNext()){
//……做事;
}
}
如果顺序不重要,你可以建立一个新的列表

List<Item> others = new ArrayList<>(list.size());
for(Item item: list){
    for(Item other: others){
        // do stuff
    }
    others.add(item);
}
List others=newarraylist(List.size());
用于(项目:列表){
项目(其他:其他){
//做事
}
其他。添加(项目);
}

如果您可以修改列表:

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

while(things.hasNext()){
    Item item = things.next();
    things.remove();
    Iterator<Item> others = list.iterator();
    while(others.hasNext()){
        //... do stuff;
    }
}
Iterator things=list.Iterator();
while(things.hasNext()){
Item=things.next();
事物。移除();
Iterator others=list.Iterator();
while(others.hasNext()){
//……做事;
}
}
如果顺序不重要,你可以建立一个新的列表

List<Item> others = new ArrayList<>(list.size());
for(Item item: list){
    for(Item other: others){
        // do stuff
    }
    others.add(item);
}
List others=newarraylist(List.size());
用于(项目:列表){
项目(其他:其他){
//做事
}
其他。添加(项目);
}

你就不能把
i
j
互换一下吗

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);
    }
}
列表x=。。。;
int j=0;
对于(ej:x){
int iMax=j++;
int i=0;
对于(ei:x){
如果(i++>=iMax)
打破
某些操作(ei、ej);
}
}

你就不能把
i
j
互换一下吗

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);
    }
}
列表x=。。。;
int j=0;
对于(ej:x){
int iMax=j++;
int i=0;
对于(ei:x){
如果(i++>=iMax)
打破
某些操作(ei、ej);
}
}


您可以将
链接列表
复制到刚开始的
数组列表
,即O(n)。然后用它进行配对操作。这是一个额外的O(n),它不会增加复杂性和一些额外的空间。如果你往另一个方向走呢。创建一个新的列表,并不断积累元素。@Boristespider你是对的,我错过了问题的这一部分。@matt我也喜欢你的方法。我认为这比你的答案更好:)事实上,第一次我必须复制整个列表,然后删除元素,而在这种方法中,我们只是在访问期间创建列表。没有任何重载。您可以将
链接列表
复制到一个
数组列表
的开头,即O(n)。然后用它进行配对操作。这是一个额外的O(n),它不会增加复杂性和一些额外的空间。如果你往另一个方向走呢。创建一个新的列表,并不断积累元素。@Boristespider你是对的,我错过了问题的这一部分。@matt我也喜欢你的方法。我认为这比你的答案更好:)事实上,第一次我必须复制整个列表,然后删除元素,而在这种方法中,我们只是在访问期间创建列表。没有任何过载..你是对的,在Big-O方面没有任何变化,但是你的代码-在链表的情况下-或多或少会花费双倍的时间,这在我看来是不好的。你是对的,在Big-O方面没有任何变化,但是你的代码-在链表的情况下-或多或少会花费双倍的时间,在我看来,这是不好的。我认为这是解决问题的最好办法,即使在做这件事之前我必须复制清单。我想知道为什么我们没有像iterator.clone()这样的东西。在我看来会容易得多。@BoristheSpider我不同意你的观点,事实上matt在删除之后创建了第二个迭代器operation@BoristheSpider我想每个人都用a,但我不确定。两个迭代器。虽然,修改列表可能会比列表迭代器解决方案增加更多的开销。@matt是的,它似乎确实有效-但是如果
其他人
修改
列表
,它显然会爆炸。我认为这是解决问题的最佳方法,即使在执行此操作之前我必须复制列表。我想知道为什么我们没有像iterator.clone()这样的东西。在我看来会容易得多。@BoristheSpider我不同意你的观点,事实上matt在删除之后创建了第二个迭代器operation@BoristheSpider我想每个人都用a,但我不确定。两个迭代器。虽然,修改列表可能会比列表迭代器解决方案增加更多的开销。@matt是的,它似乎确实有效-但如果
其他人
修改
列表
,它显然会爆炸。我认为这是迄今为止最有效的解决方案,甚至是最简单的解决方案:不涉及迭代器,并且不需要额外的内存:)Thanks@Samuele不客气。顺便说一句,迭代器隐式地包含在“for each”循环中。在我看来,这是迄今为止最有效的解决方案,甚至是最简单的解决方案:不涉及迭代器,也不需要额外的内存:)Thanks@Samuele不客气。顺便说一句,迭代器隐式地包含在“for-each”循环中。