【问题标题】:Compare every item to every other item in ArrayList将每个项目与 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]

标签: java algorithm sorting arraylist compare


【解决方案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 也不是),而是关于可读且不易出错的源代码
        猜你喜欢
        • 2020-10-16
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多