How can I calculate the difference between two ArrayLists?

I have two lists of ArrayLists.

ArrayList A contains

['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']

I need to compare ArrayLst A and ArrayLst B. The result of the ArrayList should contain a list that does not exist in ArrayList A. The result of the ArrayList should be

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

how to compare?

+79
java arraylist
May 28 '09 at 6:01 a.m.
source share
10 answers

In Java, you can use the Collection removeAll interface.

 // 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 result:

 First List: [apple, orange] Second List: [apple, orange, banana, strawberry] Result: [banana, strawberry] 
+188
May 28 '09 at 6:14 a.m.
source share

You already have the correct answer. And if you want to make more complex and interesting operations between lists (collections), use the collection of apache collections ( CollectionUtils ). This allows you to do conjunction / disjunction, find the intersection, check if one collection is a subset of other and other nice things.

+20
May 28 '09 at 7:24 a.m.
source share

In Java 8, with threads, everything is pretty simple. UPDATE: can be efficient without threads, see below.

 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 a hash set is created only once: a method reference is bound to its containing method. To do the same with lambda, one would have to have a set in a variable. Creating a variable is not a bad idea, especially if you find it unsightly or difficult to understand.

You cannot easily disprove a predicate without anything like this helper method (or explicit cast), since you cannot directly call a reference to the negation method (type inference is necessary first).

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

If the threads had a filterOut method or something like that, it would look better.




Also, @Holger gave me an idea. ArrayList has a removeAll method, optimized for repeated deletions, it only permutes its elements once. However, it uses the contains method provided by this collection, so we need to optimize this part if listA is not tiny at all.

With the previously declared listA and listB this solution does not require Java 8, and it is very efficient.

 List<String> result = new ArrayList(listB); result.removeAll(new HashSet<>(listA)); 
+12
Nov 07 '17 at 17:13
source share

EDIT: The original question did not indicate the language. My answer is in C #.

Instead, you should use a HashSet for this purpose. If you must use an ArrayList, you can use the following extension methods:

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

using a 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 
+9
May 28 '09 at 6:08 a.m.
source share

I used Guava Sets.difference .

Parameters are sets, not general collections, but a convenient way to create sets from any collection (with unique elements) is Guava ImmutableSet.copyOf (Iterable).

(This is the first time I have posted this on a related / deliberate issue , but I am copying it here because I think this is a good option that is still missing.)

+8
Sep 02 '14 at 4:55
source share

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

  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()); 
+8
Oct 11 '16 at 12:15
source share

I think you are talking about C #. If so, you can try it.

  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; } 
+2
May 28 '09 at 6:12
source share

You are simply comparing strings.

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

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

In HashTable B, you are left with strings (keys) that were not values ​​in ArrayList A.

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

 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>(); 
+1
May 28 '09 at 6:18
source share

Hi, use this class, this will compare both lists and display exactly the mismatch of the two lists.

 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; } } 
+1
Mar 07 '14 at 12:32
source share

THIS WORK ALSO WITH 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
Mar 07 '16 at 15:36
source share



All Articles