【问题标题】:Java Compare Two ListsJava比较两个列表
【发布时间】:2011-02-15 06:24:42
【问题描述】:

我有两个列表(不是java列表,你可以说两列)

例如

**List 1**            **Lists 2**
  milan                 hafil
  dingo                 iga
  iga                   dingo
  elpha                 binga
  hafil                 mike
  meat                  dingo
  milan
  elpha
  meat
  iga                   
  neeta.peeta    

我想要一个返回多少元素相同的方法。对于这个例子,它应该是 3 它也应该返回列表和不同值的相似值。

如果是,我应该使用 hashmap,然后用什么方法来得到我的结果?

请帮忙

P.S: 这不是学校作业:) 所以只要你指导我就足够了

【问题讨论】:

  • 请建议任何数据结构列表不是java列表或hashmap或任何数据结构
  • 一定要考虑在特殊情况下应该做什么。列表可以包含两次相同的值吗?如果是这样,如果“dingo”在两个列表中出现两次,这算作两个共同的元素还是只有一个?
  • 你能修改其中一个列表吗?
  • 如何编辑??是的,每个列表都可以多次包含相似的值
  • 问题后面应该有一个edit小链接,标签下方。

标签: java list comparison hashmap


【解决方案1】:

编辑

这里有两个版本。一个使用ArrayList,另一个使用HashSet

比较它们并从中创建你的自己的版本,直到你得到你需要的东西。

这应该足以涵盖:

P.S:这不是学校作业 :) 所以如果你只是指导我就足够了

您的问题的一部分。

继续原来的答案:

您可以为此使用java.util.Collection 和/或java.util.ArrayList

retainAll 方法执行以下操作:

仅保留该集合中包含在指定集合中的元素

查看此示例:

import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;

public class Repeated {
    public static void main( String  [] args ) {
        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));

        listOne.retainAll( listTwo );
        System.out.println( listOne );
    }
}

编辑

对于第二部分(类似的值),您可以使用removeAll 方法:

删除该集合中所有也包含在指定集合中的元素。

第二个版本也为您提供了相似的值和重复处理(通过丢弃它们)。

这次Collection 可能是Set 而不是List(不同的是,Set 不允许重复值)

import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;

class Repeated {
      public static void main( String  [] args ) {

          Collection<String> listOne = Arrays.asList("milan","iga",
                                                    "dingo","iga",
                                                    "elpha","iga",
                                                    "hafil","iga",
                                                    "meat","iga", 
                                                    "neeta.peeta","iga");

          Collection<String> listTwo = Arrays.asList("hafil",
                                                     "iga",
                                                     "binga", 
                                                     "mike", 
                                                     "dingo","dingo","dingo");

          Collection<String> similar = new HashSet<String>( listOne );
          Collection<String> different = new HashSet<String>();
          different.addAll( listOne );
          different.addAll( listTwo );

          similar.retainAll( listTwo );
          different.removeAll( similar );

          System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
      }
}

输出:

$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]

Two:[hafil, iga, binga, mike, dingo, dingo, dingo]

Similar:[dingo, iga, hafil]

Different:[mike, binga, milan, meat, elpha, neeta.peeta]

如果它不能完全满足您的需求,它会为您提供一个良好的开端,以便您可以从这里处理。

读者问题:如何包含所有重复的值?

【讨论】:

  • @Oscar,我的确切想法,但我不确定我们是否可以修改 listOne 的内容,但无论如何 +1!
  • @poygenelubricants 你说的原始类型不是泛型是什么意思?为什么不呢?
  • 奥斯卡,你看到我更新的问题了吗?是否支持重复值?
  • @Oscar: java.sun.com/docs/books/jls/third_edition/html/… "强烈反对在将泛型引入 Java 编程语言后编写的代码中使用原始类型。Java 编程语言的未来版本可能会禁止使用原始类型。”
  • @polygenelubricants 答案已更新以处理重复和原始类型。顺便说一句,..Java 的未来版本... 永远不会发生。 ;)
【解决方案2】:

您可以尝试CollectionUtils 中的intersection()subtract() 方法。

intersection() 方法为您提供包含常见元素的集合,subtract() 方法为您提供所有不常见的元素。

他们也应该照顾类似的元素

【讨论】:

  • 应该注意这个解决方案需要Apache Ccommons
【解决方案3】:

这些真的是lists(有序,有重复),还是sets(无序,无重复)?

因为如果是后者,那么您可以使用 java.util.HashSet&lt;E&gt; 并使用方便的 retainAll 在预期的线性时间内执行此操作。

    List<String> list1 = Arrays.asList(
        "milan", "milan", "iga", "dingo", "milan"
    );
    List<String> list2 = Arrays.asList(
        "hafil", "milan", "dingo", "meat"
    );

    // intersection as set
    Set<String> intersect = new HashSet<String>(list1);
    intersect.retainAll(list2);
    System.out.println(intersect.size()); // prints "2"
    System.out.println(intersect); // prints "[milan, dingo]"

    // intersection/union as list
    List<String> intersectList = new ArrayList<String>();
    intersectList.addAll(list1);
    intersectList.addAll(list2);
    intersectList.retainAll(intersect);
    System.out.println(intersectList);
    // prints "[milan, milan, dingo, milan, milan, dingo]"

    // original lists are structurally unmodified
    System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
    System.out.println(list2); // prints "[hafil, milan, dingo, meat]"

【讨论】:

  • 好吧,我真的不知道应该是哪种数据结构。它有重复项。现在您可以看到更新的问题
  • 它会从数据集中删除重复的值吗?因为我不想失去任何价值:(
  • @agazerboy:我已经尝试解决这两个问题。随时要求更多说明。
  • 感谢聚。我尝试了您的程序重复项,例如在第一个列表中我添加了两次“iga”,但它仍然返回 3 作为答案。虽然现在应该是 4。因为列表 1 有 4 个相似的值。如果我多次添加一个条目,它应该可以工作。你说什么?还有其他数据结构吗?
【解决方案4】:

如果您正在寻找一种方便的方法来测试两个集合的相等性,您可以使用org.apache.commons.collections.CollectionUtils.isEqualCollection,它比较两个集合而不考虑排序。

【讨论】:

    【解决方案5】:

    使用 java 8 removeIf

    public int getSimilarItems(){
        List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
        List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
        int initial = two.size();
    
        two.removeIf(one::contains);
        return initial - two.size();
    }
    

    【讨论】:

    • 看起来不错,但如果我想保持列表不变,我将不得不克隆其中一个列表,在某些情况下这是不希望的。
    【解决方案6】:

    在所有方法中,我发现使用org.apache.commons.collections.CollectionUtils#isEqualCollection 是最好的方法。原因如下——

    • 我不必自己声明任何其他列表/设置
    • 我没有改变输入列表
    • 非常有效。它检查 O(N) 复杂度的相等性。

    如果不可能将apache.commons.collections 作为依赖项,我建议实现它所遵循的算法来检查列表的相等性,因为它的效率很高。

    【讨论】:

      【解决方案7】:

      简单的解决方案:-

          List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
          List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));
      
          list.retainAll(list2);
          list2.removeAll(list);
          System.out.println("similiar " + list);
          System.out.println("different " + list2);
      

      输出:-

      similiar [b, c]
      different [f]
      

      【讨论】:

        【解决方案8】:

        假设hash1hash2

        List< String > sames = whatever
        List< String > diffs = whatever
        
        int count = 0;
        for( String key : hash1.keySet() )
        {
           if( hash2.containsKey( key ) ) 
           {
              sames.add( key );
           }
           else
           {
              diffs.add( key );
           }
        }
        
        //sames.size() contains the number of similar elements.
        

        【讨论】:

        • 他想要相同键的列表,而不是有多少键相同。我想。
        • 感谢 stefan 的帮助。是的,罗斯迪是正确的,你也是。我还需要相似值和相似值的总数。
        【解决方案9】:

        我在List Compare 找到了一个非常基本的列表比较示例 此示例首先验证大小,然后检查一个列表的特定元素在另一个列表中的可用性。

        【讨论】:

          【解决方案10】:
          public static boolean compareList(List ls1, List ls2){
              return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
               }
          
          public static void main(String[] args) {
          
              ArrayList<String> one = new ArrayList<String>();
              one.add("one");
              one.add("two");
              one.add("six");
          
              ArrayList<String> two = new ArrayList<String>();
              two.add("one");
              two.add("six");
              two.add("two");
          
              System.out.println("Output1 :: " + compareList(one, two));
          
              two.add("ten");
          
              System.out.println("Output2 :: " + compareList(one, two));
            }
          

          【讨论】:

          • 当两个包含 3 个“一”副本时,此解决方案返回错误结果。它会错误地产生一个真实的结果。
          • 感谢这部分:&& ls1.size() == ls2.size()
          • 您认为在您的 sn-p 中需要 ? true :false 的任何原因?
          猜你喜欢
          • 1970-01-01
          • 2013-06-10
          • 1970-01-01
          • 1970-01-01
          • 2011-06-19
          • 2016-05-05
          • 1970-01-01
          相关资源
          最近更新 更多