如何计算两个ArrayLists之间的差异?

时间:2021-02-01 07:16:21

I have two ArrayLists.

我有两个ArrayLists。

ArrayList A contains

ArrayList A包含

['2009-05-18','2009-05-19','2009-05-21']

ArrayList B Contains ['2009-05-18','2009-05-18','2009-05-19','2009-05-19','2009-05-20','2009-05-21','2009-05-21','2009-05-22']

ArrayList B包含['2009-05-18','2009-05-18','2009-05-19','2009-05-19','2009-05-20','2009-05-21 ”, '2009-05-21', '2009-05-22']

I have to compare ArrayLst A and ArrayLst B . The result ArrayList should contain the List which does not exist in ArrayList A. ArrayList result should be

我必须比较ArrayLst A和ArrayLst B.结果ArrayList应该包含ArrayList中不存在的List .AllList结果应该是

['2009-05-20','2009-05-22']

[ '2009-05-20', '2009-05-22']

how to compare ?

怎么比较?

10 个解决方案

#1


161  

In Java, you can use the Collection interface's removeAll method.

在Java中,您可以使用Collection接口的removeAll方法。

// Create a couple ArrayList objects and populate them
// with some delicious fruits.
Collection firstList = new ArrayList() {{
    add("apple");
    add("orange");
}};

Collection secondList = new ArrayList() {{
    add("apple");
    add("orange");
    add("banana");
    add("strawberry");
}};

// Show the "before" lists
System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Remove all elements in firstList from secondList
secondList.removeAll(firstList);

// Show the "after" list
System.out.println("Result: " + secondList);

The above code will produce the following output:

上面的代码将产生以下输出:

First List: [apple, orange]
Second List: [apple, orange, banana, strawberry]
Result: [banana, strawberry]

#2


19  

You already have the right answer. And if you want to make more complicated and interesting operations between Lists (collections) use apache commons collections (CollectionUtils) It allows you to make conjuction/disjunction, find intersection, check if one collection is a subset of another and other nice things.

你已经有了正确的答案。如果你想在列表(集合)之间进行更复杂和有趣的操作,请使用apache commons集合(CollectionUtils)它允许你进行结合/分离,查找交集,检查一个集合是否是另一个集合的子集以及其他好东西。

#3


9  

EDIT: Original question did not specify language. My answer is in C#.

编辑:原始问题没有指定语言。我的答案是在C#中。

You should instead use HashSet for this purpose. If you must use ArrayList, you could use the following extension methods:

您应该使用HashSet来实现此目的。如果必须使用ArrayList,则可以使用以下扩展方法:

var a = arrayListA.Cast<DateTime>();
var b = arrayListB.Cast<DateTime>();    
var c = b.Except(a);

var arrayListC = new ArrayList(c.ToArray());

using HashSet...

使用HashSet ...

var a = new HashSet<DateTime>(); // ...and fill it
var b = new HashSet<DateTime>(); // ...and fill it
b.ExceptWith(a); // removes from b items that are in a

#4


7  

I have used Guava Sets.difference.

我使用过Guava Sets.difference。

The parameters are sets and not general collections, but a handy way to create sets from any collection (with unique items) is Guava ImmutableSet.copyOf(Iterable).

参数是集合而不是一般集合,但是从任何集合(具有唯一项目)创建集合的便捷方式是Guava ImmutableSet.copyOf(Iterable)。

(I first posted this on a related/dupe question, but I'm copying it here too since I feel it is a good option that is so far missing.)

(我首先在一个相关的/重复问题上发布了这个问题,但我也在这里复制它,因为我认为这是一个迄今为止缺失的好选项。)

#5


6  

Although this is a very old question in Java 8 you could do something like

虽然这是Java 8中一个非常古老的问题,但你可以做类似的事情

 List<String> a1 = Arrays.asList("2009-05-18", "2009-05-19", "2009-05-21");
 List<String> a2 = Arrays.asList("2009-05-18", "2009-05-18", "2009-05-19", "2009-05-19", "2009-05-20", "2009-05-21","2009-05-21", "2009-05-22");

 List<String> result = a2.stream().filter(elem -> !a1.contains(elem)).collect(Collectors.toList());

`

`

#6


6  

In Java 8 with streams, it's pretty simple actually.

在带有流的Java 8中,它实际上非常简单。

List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
                                   "2009-05-20","2009-05-21","2009-05-21","2009-05-22");

List<String> result = listB.stream()
                           .filter(not(new HashSet<>(listA)::contains))
                           .collect(Collectors.toList());

Note that the hash set is only created once: The method referrence is tied to its contains method. Lambda would require a variable for the set to work identically. Make a variable anyway, if you have readability issues with this.

请注意,哈希集仅创建一次:方法引用与其contains方法相关联。 Lambda将要求集合的变量以相同的方式工作。如果你有可读性问题,无论如何都要做一个变量。

You can't easily negate the predicate without something like this utility method (or explicit cast), as you can't call the negate method reference directly (type inference is needed first).

如果没有像这个实用方法(或显式转换)之类的东西,你不能轻易否定谓词,因为你不能直接调用negate方法引用(首先需要类型推断)。

private static <T> Predicate<T> not(Predicate<T> predicate) {
    return predicate.negate();
}

If streams had a filterOut method or something, it would look nicer.

如果stream有一个filterOut方法或其他东西,它会看起来更好。

#7


2  

I guess you're talking about C#. If so, you can try this

我想你在谈论C#。如果是这样,你可以试试这个

    ArrayList CompareArrayList(ArrayList a, ArrayList b)
    {
        ArrayList output = new ArrayList();
        for (int i = 0; i < a.Count; i++)
        {
            string str = (string)a[i];
            if (!b.Contains(str))
            {
                if(!output.Contains(str)) // check for dupes
                    output.Add(str);
            }
        }
        return output;
    }

#8


1  

You are just comparing strings.

你只是比较字符串。

Put the values in ArrayList A as keys in HashTable A.
Put the values in ArrayList B as keys in HashTable B.

将ArrayList A中的值作为HashTable A中的键。将ArrayList B中的值作为HashTable B中的键。

Then, for each key in HashTable A, remove it from HashTable B if it exists.

然后,对于HashTable A中的每个键,将其从HashTable B中删除(如果存在)。

What you are left with in HashTable B are the strings (keys) that were not values in ArrayList A.

你在HashTable B中剩下的是字符串(键),它们不是ArrayList A中的值。

C# (3.0) example added in response to request for code:

响应代码请求添加了C#(3.0)示例:

List<string> listA = new List<string>{"2009-05-18","2009-05-19","2009-05-21'"};
List<string> listB = new List<string>{"2009-05-18","2009-05-18","2009-05-19","2009-05-19","2009-05-20","2009-05-21","2009-05-21","2009-05-22"};

HashSet<string> hashA = new HashSet<string>();
HashSet<string> hashB = new HashSet<string>();

foreach (string dateStrA in listA) hashA.Add(dateStrA);
foreach (string dateStrB in listB) hashB.Add(dateStrB);

foreach (string dateStrA in hashA)
{
    if (hashB.Contains(dateStrA)) hashB.Remove(dateStrA);
}

List<string> result = hashB.ToList<string>();

#9


1  

Hi use this class this will compare both lists and shows exactly the mismatch b/w both lists.

嗨使用这个类,这将比较两个列表,并准确显示两个列表的不匹配b / w。

import java.util.ArrayList;
import java.util.List;


public class ListCompare {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<String> dbVinList;
        dbVinList = new ArrayList<String>();
        List<String> ediVinList;
        ediVinList = new ArrayList<String>();           

        dbVinList.add("A");
        dbVinList.add("B");
        dbVinList.add("C");
        dbVinList.add("D");

        ediVinList.add("A");
        ediVinList.add("C");
        ediVinList.add("E");
        ediVinList.add("F");
        /*ediVinList.add("G");
        ediVinList.add("H");
        ediVinList.add("I");
        ediVinList.add("J");*/  

        List<String> dbVinListClone = dbVinList;
        List<String> ediVinListClone = ediVinList;

        boolean flag;
        String mismatchVins = null;
        if(dbVinListClone.containsAll(ediVinListClone)){
            flag = dbVinListClone.removeAll(ediVinListClone);   
            if(flag){
                mismatchVins = getMismatchVins(dbVinListClone);
            }
        }else{
            flag = ediVinListClone.removeAll(dbVinListClone);
            if(flag){
                mismatchVins = getMismatchVins(ediVinListClone);
            }
        }
        if(mismatchVins != null){
            System.out.println("mismatch vins : "+mismatchVins);
        }       

    }

    private static String getMismatchVins(List<String> mismatchList){
        StringBuilder mismatchVins = new StringBuilder();
        int i = 0;
        for(String mismatch : mismatchList){
            i++;
            if(i < mismatchList.size() && i!=5){
                mismatchVins.append(mismatch).append(",");  
            }else{
                mismatchVins.append(mismatch);
            }
            if(i==5){               
                break;
            }
        }
        String mismatch1;
        if(mismatchVins.length() > 100){
            mismatch1 = mismatchVins.substring(0, 99);
        }else{
            mismatch1 = mismatchVins.toString();
        }       
        return mismatch1;
    }

}

#10


1  

THIS WORK ALSO WITH Arraylist

这项工作也适用于Arraylist

    // Create a couple ArrayList objects and populate them
    // with some delicious fruits.
    ArrayList<String> firstList = new ArrayList<String>() {/**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("apple");
        add("orange");
        add("pea");
    }};

    ArrayList<String> secondList = new ArrayList<String>() {

    /**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("apple");
        add("orange");
        add("banana");
        add("strawberry");
    }};

    // Show the "before" lists
    System.out.println("First List: " + firstList);
    System.out.println("Second List: " + secondList);

    // Remove all elements in firstList from secondList
    secondList.removeAll(firstList);

    // Show the "after" list
    System.out.println("Result: " + secondList);

#1


161  

In Java, you can use the Collection interface's removeAll method.

在Java中,您可以使用Collection接口的removeAll方法。

// Create a couple ArrayList objects and populate them
// with some delicious fruits.
Collection firstList = new ArrayList() {{
    add("apple");
    add("orange");
}};

Collection secondList = new ArrayList() {{
    add("apple");
    add("orange");
    add("banana");
    add("strawberry");
}};

// Show the "before" lists
System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);

// Remove all elements in firstList from secondList
secondList.removeAll(firstList);

// Show the "after" list
System.out.println("Result: " + secondList);

The above code will produce the following output:

上面的代码将产生以下输出:

First List: [apple, orange]
Second List: [apple, orange, banana, strawberry]
Result: [banana, strawberry]

#2


19  

You already have the right answer. And if you want to make more complicated and interesting operations between Lists (collections) use apache commons collections (CollectionUtils) It allows you to make conjuction/disjunction, find intersection, check if one collection is a subset of another and other nice things.

你已经有了正确的答案。如果你想在列表(集合)之间进行更复杂和有趣的操作,请使用apache commons集合(CollectionUtils)它允许你进行结合/分离,查找交集,检查一个集合是否是另一个集合的子集以及其他好东西。

#3


9  

EDIT: Original question did not specify language. My answer is in C#.

编辑:原始问题没有指定语言。我的答案是在C#中。

You should instead use HashSet for this purpose. If you must use ArrayList, you could use the following extension methods:

您应该使用HashSet来实现此目的。如果必须使用ArrayList,则可以使用以下扩展方法:

var a = arrayListA.Cast<DateTime>();
var b = arrayListB.Cast<DateTime>();    
var c = b.Except(a);

var arrayListC = new ArrayList(c.ToArray());

using HashSet...

使用HashSet ...

var a = new HashSet<DateTime>(); // ...and fill it
var b = new HashSet<DateTime>(); // ...and fill it
b.ExceptWith(a); // removes from b items that are in a

#4


7  

I have used Guava Sets.difference.

我使用过Guava Sets.difference。

The parameters are sets and not general collections, but a handy way to create sets from any collection (with unique items) is Guava ImmutableSet.copyOf(Iterable).

参数是集合而不是一般集合,但是从任何集合(具有唯一项目)创建集合的便捷方式是Guava ImmutableSet.copyOf(Iterable)。

(I first posted this on a related/dupe question, but I'm copying it here too since I feel it is a good option that is so far missing.)

(我首先在一个相关的/重复问题上发布了这个问题,但我也在这里复制它,因为我认为这是一个迄今为止缺失的好选项。)

#5


6  

Although this is a very old question in Java 8 you could do something like

虽然这是Java 8中一个非常古老的问题,但你可以做类似的事情

 List<String> a1 = Arrays.asList("2009-05-18", "2009-05-19", "2009-05-21");
 List<String> a2 = Arrays.asList("2009-05-18", "2009-05-18", "2009-05-19", "2009-05-19", "2009-05-20", "2009-05-21","2009-05-21", "2009-05-22");

 List<String> result = a2.stream().filter(elem -> !a1.contains(elem)).collect(Collectors.toList());

`

`

#6


6  

In Java 8 with streams, it's pretty simple actually.

在带有流的Java 8中,它实际上非常简单。

List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
                                   "2009-05-20","2009-05-21","2009-05-21","2009-05-22");

List<String> result = listB.stream()
                           .filter(not(new HashSet<>(listA)::contains))
                           .collect(Collectors.toList());

Note that the hash set is only created once: The method referrence is tied to its contains method. Lambda would require a variable for the set to work identically. Make a variable anyway, if you have readability issues with this.

请注意,哈希集仅创建一次:方法引用与其contains方法相关联。 Lambda将要求集合的变量以相同的方式工作。如果你有可读性问题,无论如何都要做一个变量。

You can't easily negate the predicate without something like this utility method (or explicit cast), as you can't call the negate method reference directly (type inference is needed first).

如果没有像这个实用方法(或显式转换)之类的东西,你不能轻易否定谓词,因为你不能直接调用negate方法引用(首先需要类型推断)。

private static <T> Predicate<T> not(Predicate<T> predicate) {
    return predicate.negate();
}

If streams had a filterOut method or something, it would look nicer.

如果stream有一个filterOut方法或其他东西,它会看起来更好。

#7


2  

I guess you're talking about C#. If so, you can try this

我想你在谈论C#。如果是这样,你可以试试这个

    ArrayList CompareArrayList(ArrayList a, ArrayList b)
    {
        ArrayList output = new ArrayList();
        for (int i = 0; i < a.Count; i++)
        {
            string str = (string)a[i];
            if (!b.Contains(str))
            {
                if(!output.Contains(str)) // check for dupes
                    output.Add(str);
            }
        }
        return output;
    }

#8


1  

You are just comparing strings.

你只是比较字符串。

Put the values in ArrayList A as keys in HashTable A.
Put the values in ArrayList B as keys in HashTable B.

将ArrayList A中的值作为HashTable A中的键。将ArrayList B中的值作为HashTable B中的键。

Then, for each key in HashTable A, remove it from HashTable B if it exists.

然后,对于HashTable A中的每个键,将其从HashTable B中删除(如果存在)。

What you are left with in HashTable B are the strings (keys) that were not values in ArrayList A.

你在HashTable B中剩下的是字符串(键),它们不是ArrayList A中的值。

C# (3.0) example added in response to request for code:

响应代码请求添加了C#(3.0)示例:

List<string> listA = new List<string>{"2009-05-18","2009-05-19","2009-05-21'"};
List<string> listB = new List<string>{"2009-05-18","2009-05-18","2009-05-19","2009-05-19","2009-05-20","2009-05-21","2009-05-21","2009-05-22"};

HashSet<string> hashA = new HashSet<string>();
HashSet<string> hashB = new HashSet<string>();

foreach (string dateStrA in listA) hashA.Add(dateStrA);
foreach (string dateStrB in listB) hashB.Add(dateStrB);

foreach (string dateStrA in hashA)
{
    if (hashB.Contains(dateStrA)) hashB.Remove(dateStrA);
}

List<string> result = hashB.ToList<string>();

#9


1  

Hi use this class this will compare both lists and shows exactly the mismatch b/w both lists.

嗨使用这个类,这将比较两个列表,并准确显示两个列表的不匹配b / w。

import java.util.ArrayList;
import java.util.List;


public class ListCompare {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<String> dbVinList;
        dbVinList = new ArrayList<String>();
        List<String> ediVinList;
        ediVinList = new ArrayList<String>();           

        dbVinList.add("A");
        dbVinList.add("B");
        dbVinList.add("C");
        dbVinList.add("D");

        ediVinList.add("A");
        ediVinList.add("C");
        ediVinList.add("E");
        ediVinList.add("F");
        /*ediVinList.add("G");
        ediVinList.add("H");
        ediVinList.add("I");
        ediVinList.add("J");*/  

        List<String> dbVinListClone = dbVinList;
        List<String> ediVinListClone = ediVinList;

        boolean flag;
        String mismatchVins = null;
        if(dbVinListClone.containsAll(ediVinListClone)){
            flag = dbVinListClone.removeAll(ediVinListClone);   
            if(flag){
                mismatchVins = getMismatchVins(dbVinListClone);
            }
        }else{
            flag = ediVinListClone.removeAll(dbVinListClone);
            if(flag){
                mismatchVins = getMismatchVins(ediVinListClone);
            }
        }
        if(mismatchVins != null){
            System.out.println("mismatch vins : "+mismatchVins);
        }       

    }

    private static String getMismatchVins(List<String> mismatchList){
        StringBuilder mismatchVins = new StringBuilder();
        int i = 0;
        for(String mismatch : mismatchList){
            i++;
            if(i < mismatchList.size() && i!=5){
                mismatchVins.append(mismatch).append(",");  
            }else{
                mismatchVins.append(mismatch);
            }
            if(i==5){               
                break;
            }
        }
        String mismatch1;
        if(mismatchVins.length() > 100){
            mismatch1 = mismatchVins.substring(0, 99);
        }else{
            mismatch1 = mismatchVins.toString();
        }       
        return mismatch1;
    }

}

#10


1  

THIS WORK ALSO WITH Arraylist

这项工作也适用于Arraylist

    // Create a couple ArrayList objects and populate them
    // with some delicious fruits.
    ArrayList<String> firstList = new ArrayList<String>() {/**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("apple");
        add("orange");
        add("pea");
    }};

    ArrayList<String> secondList = new ArrayList<String>() {

    /**
         * 
         */
        private static final long serialVersionUID = 1L;

    {
        add("apple");
        add("orange");
        add("banana");
        add("strawberry");
    }};

    // Show the "before" lists
    System.out.println("First List: " + firstList);
    System.out.println("Second List: " + secondList);

    // Remove all elements in firstList from secondList
    secondList.removeAll(firstList);

    // Show the "after" list
    System.out.println("Result: " + secondList);