将每个项目与 ArrayList 中的每个其他项目进行比较

Posted

技术标签:

【中文标题】将每个项目与 ArrayList 中的每个其他项目进行比较【英文标题】:Compare every item to every other item in ArrayList 【发布时间】:2011-06-27 00:18:35 【问题描述】:

我遇到了一个我认为应该很简单的问题。

我需要将 arrayList 中的每个项目与列表中的每个其他项目进行比较,而不需要将项目与它们自己进行比较。它不像调用 equals() 比较那么简单,它涉及一些我在下面的代码中省略的自定义逻辑。此外,不应以任何方式更改 ArrayList。

我似乎遇到的问题是,一旦我进入第二个循环,我不知道我是否还有另一个对象可以比较(因为它是一个可变大小的列表)。

for(int i =0; i< list.size(); i++) 
    //get first object to compare to
    String a = list.get(i).getA();

    Iterator itr = list.listIterator(i + 1 ); // I don't know if i + 1 is valid
    while(itr.hasNext())
        // compare A to all remaining items on list
    

我认为我可能以错误的方式处理此问题,我愿意接受有关如何更好地执行此操作的建议或提示。

【问题讨论】:

您说 ArrayList 不应以任何方式更改,因此列表的大小不是可变的:它是恒定的。因此,i+1 将是 listIterator() 的有效索引,因为 i 保证为 太棒了,这个问题对我帮助很大! 在CR,这可能适合不像看起来那么容易类别(尤其是非对称compare和一般java.util.List&lt;&gt;。从compare every item in [a List L] with every other item in [L] 【参考方案1】:

你可以这样做。

for (int i = 0; i < arrayList.size(); i++) 
    for (int j = 0; j < arrayList.size(); j++) 
        if (i!=j &&  arrayList.get(i).YourObjectItem().equals(arrayList.get(j).YourObjectItem())) 
            //Your code will be here
        

    

【讨论】:

【参考方案2】:

在某些情况下,这是最好的方法,因为您的代码可能已更改某些内容,而 j=i+1 不会检查。

for (int i = 0; i < list.size(); i++)  
    for (int j = 0; j < list.size(); j++) 
                if(i == j) 
               //to do code here
                    continue;
                


【讨论】:

一种compare every item in [a List L] with every other item in [L]的解释。可能是时候考虑/提出基于 java.util.stream 的方法了 - 可惜 Stream 必须是可克隆的,并提供与 Iterator 一样有用的 equals()【参考方案3】:

这段代码帮助我实现了这种行为:对于列表 a、b、c,我应该比较 ab、ac 和 bc,但任何其他对都将是多余的/不需要。

import java.util.*;
import static java.lang.System.out;

// rl = rawList; lr = listReversed
ArrayList<String> rl = new ArrayList<String>();
ArrayList<String> lr = new ArrayList<String>();
rl.add("a");
rl.add("b");
rl.add("c");
rl.add("d");
rl.add("e");
rl.add("f");

lr.addAll(rl);
Collections.reverse(lr);

for (String itemA : rl) 
    lr.remove(lr.size()-1);
        for (String itemZ : lr) 
        System.out.println(itemA + itemZ);
    

循环如下图所示: Triangular comparison visual example

或者这样:

   |   f    e    d    c    b   a
   ------------------------------
a  |  af   ae   ad   ac   ab   ·
b  |  bf   be   bd   bc   ·   
c  |  cf   ce   cd   ·      
d  |  df   de   ·         
e  |  ef   ·            
f  |  ·               

总比较是一个三角数 (n * n-1)/2

【讨论】:

【参考方案4】:

下面的代码将使用 contains() 方法将每个项目与其他项目列表进行比较。for 循环的长度必须大于更大列表的 size(),然后才会比较两个列表的所有值。

List<String> str = new ArrayList<String>();
str.add("first");
str.add("second");
str.add("third");
List<String> str1 = new ArrayList<String>();
str1.add("first");
str1.add("second");
str1.add("third1");
for (int i = 0; i<str1.size(); i++)

System.out.println(str.contains(str1.get(i)));

输出为真 真的 假的

【讨论】:

【参考方案5】:
for (int i = 0; i < list.size(); i++) 
  for (int j = i+1; j < list.size(); j++) 
    // compare list.get(i) and list.get(j)
  

【讨论】:

这将进行比要求更多的比较,您将测试 item1 == item3 和 item3 == item1 是的,刚刚意识到它在做一些不必要的比较,更新了代码。 @Mike 不,因为内循环只接受外循环中当前索引“后面”的元素。 我一开始初始化 j = 0,然后修复它。 是的,这确实有效,我不确定我为什么要尝试使用迭代器,我认为这是获取子列表的唯一方法。解决方案很简单,我只是在想这个。谢谢【参考方案6】:

在内部使用for 循环有什么问题,就像在外部一样?

for (int j = i + 1; j < list.size(); ++j) 
    ...

一般来说,从 Java 5 开始,我只使用过一次或两次迭代器。

【讨论】:

你应该阅读 Effective Java item 46,它明确建议不要使用传统的 for 循环(尽可能) @Sean Patrick Floyd,如果需要,JVM 可以为此使用内在函数。我现在不说它确实使用但迭代器是最容易优化的东西(通过逃逸分析) @bestsss 我不是在谈论有效的字节码(在这种情况下,Josh Bloch 也不是),而是关于可读且不易出错的源代码

以上是关于将每个项目与 ArrayList 中的每个其他项目进行比较的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList、for 循环和 if 语句的问题 - 为列表中的每个项目打印行

制作 ListView 时遇到问题,其中每个项目都显示模型的 ArrayList

读取和写入.List文件的ArrayList

如果其他ArrayList中的条件为true,如何从ArrayList中删除项目

如何将每个项目添加到 listview android

如何将列表中的每个项目与Python中另一个列表的所有值一起使用[重复]