【问题标题】:find out the elements of an arraylist which is not present in another arraylist找出另一个数组列表中不存在的数组列表的元素
【发布时间】:2012-10-28 11:17:29
【问题描述】:

我必须找到一种最好的方法来找出第二个数组列表中没有出现的元素。 假设

Arraylist a,b, 

Arraylist a={1,2,3,4,5};
Arraylist b={2,3,4};

所以基本上我想要的是找出 arraylist b 中不存在的 a 元素。

那么最好的解决方案是什么?

【问题讨论】:

  • @arvin_codeHunk 输入数组是否以任何方式排序?

标签: java arrays list collections arraylist


【解决方案1】:

您可以使用Apache Commons Collections,它有一个明确用于此目的的方法:

public static void main(String[] args) {
    List<Integer> a = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 });
    List<Integer> b = Arrays.asList(new Integer[] { 2, 3, 4 });
    Collection<Integer> aMinusB = CollectionUtils.subtract(a, b);
    System.out.println(aMinusB);
}

打印结果为:[1, 5].

Apache Commons 库经过充分测试,通常用于扩展标准 Java 功能。这个特定的方法接受Iterable 作为参数,所以你可以使用任何你想要的Collection。您还可以混合使用不同的集合类型:

public static void main(String[] args) {
    List<Integer> a = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 });
    Set<Integer> b = new HashSet<Integer>(Arrays.asList(new Integer[] { 2, 3, 4 }));
    Collection<Integer> aMinusB = CollectionUtils.subtract(a, b);
    System.out.println(aMinusB);
}

打印结果是一样的,[1, 5]。

查看 Javadoc here。


为了完整起见,谷歌的Guava库does not have this feature:

Collection *subtract*(Collection, Collection)
没有等价物——创建一个包含 a 的 ArrayList,然后对 b 中的每个元素调用 remove。

但是,它实现了一个名为 Sets.difference() 的方法,如果您更喜欢 Guava 并使用集合,则可以使用该方法:

public static void main(String[] args) {
    Set<Integer> a = new HashSet<Integer>(Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 }));
    Set<Integer> b = new HashSet<Integer>(Arrays.asList(new Integer[] { 2, 3, 4 }));
    Set<Integer> aMinusB = Sets.difference(a, b);
    System.out.println(aMinusB);
}

结果是a 中不存在于b 中的所有元素(即再次[1, 5])。当然,顺序是不确定的,因为它是在集合上操作的。

【讨论】:

    【解决方案2】:

    这是使用 java 8 的另一种方法 -

    a.stream().filter(b::contains).collect(Collectors.toList());
    

    【讨论】:

    • 如果它更详细,我会喜欢这个答案。例如,正如@NamHoang 在另一个答案中所说,这将使用您的 equals 方法。除此之外,+1 用于在旧问题中引入新概念。
    • 这将找到a中存在于b中的所有项目,关于在a中查找项目的问题在b中不存在。
    • @Al-Mothafar a.stream().filter(element -&gt; !b.contains(element)).collect(Collectors.toList());...
    【解决方案3】:

    使用org.apache.commons.collections4.ListUtils

    给定

    List<Integer> a = Arrays.asList(new Integer[]{  1,2,3,4,5});
    List<Integer> b = Arrays.asList(new Integer[]{0,1,2,3});
    

    动作

    List<Integer> c = ListUtils.removeAll(b, a)
    

    列表 c 中的结果

    4, 5
    

    【讨论】:

    • 尽管您已经提出了一个四年前的问题,但是将您使用 Apache ListUtils 的解决方案与 Magnilex 使用 Apache CollectionUtils 的解决方案进行比较是很有趣的。尽管它们看起来做同样的事情,但它们的行为却有细微的不同 - 请参阅他们的文档。
    • 我喜欢有人想到了完整的问题并让 b 具有 a 中不存在的元素。谢谢。
    【解决方案4】:

    试试这个:

     public static void main(String[] args) {
            List<Integer> a = new ArrayList<Integer>();
            List<Integer> b = new ArrayList<Integer>();
            List<Integer> exclusion = new ArrayList<Integer>();
    
            a.add(1);
            a.add(2);
            a.add(3);
            a.add(4);
    
            b.add(1);
            b.add(2);
            b.add(3);
            b.add(5);
    
            for (Integer x : a) {
                if (!b.contains(x)) {
                    exclusion.add(x);
                }
            }
    
            for (Integer x : exclusion) {
                System.out.println(x);
            }
    
        }
    

    【讨论】:

      【解决方案5】:

      试试这个...

      使用 List 的contains() 方法。

      ArrayList<Integer> aList = new ArrayList<Integer>();
      
      for (Integer i : a){
      
            if (!(b.contains(i))){
      
                   aList.add(i);
      
             }
      
           else{
                   continue;
      
            }
      
       }
      

      【讨论】:

        【解决方案6】:

        类似的东西。如果您认为a 中可能存在重复项,您可以尝试另一种类型的Collection,例如Set 对应notPresent。

           List<Integer> notPresent = new ArrayList<Integer>();
        
            for (Integer n : a){
             if (!b.contains(n)){
               notPresent.add(n);
             }
            }
        

        【讨论】:

          【解决方案7】:
          List<Integer> c = new ArrayList<>(a);
          c.removeAll(b);
          

          还可以考虑使用 Sets 而不是 Lists。

          【讨论】:

          • 小心! removeAll() 使用 equals() 比较元素。因此,您可能无法获得所需的行为。
          【解决方案8】:

          遍历一个列表,然后检查其他列表中的每个元素是否使用contains。

          【讨论】:

            【解决方案9】:

            请这样尝试

            for (Object o : a) {  
              if (!b.contains(o)) {  
                // this is not present
              }  
            }  
            

            【讨论】:

              【解决方案10】:

              你可以试试removeAll:

              List<Integer> notPresent = new ArrayList<Integer>(a);
              notPresent.removeAll(b);
              

              【讨论】:

              • - 使用泛型参数而不是原始类型 - removeAll 返回布尔值而不是列表
              • 这不是一个好习惯,有什么方法可以自动排序和搜索
              • 正如@Puce 所指出的,您最好使用集合而不是列表。对于此类操作,它们的速度更快。
              • 如果我使用 Hashset 会怎样,比如这个 hashset h; h.add(a); h.add(b);然后遍历这个集合
              • @arvin_codeHunk 如果您需要对所有数字进行排序,您可以使用 TreeSet。
              猜你喜欢
              • 2020-05-22
              • 2023-03-23
              • 2020-11-17
              • 2016-09-19
              • 2017-08-20
              • 1970-01-01
              • 2020-10-15
              • 2019-03-25
              • 1970-01-01
              相关资源
              最近更新 更多