Как я могу рассчитать разницу между двумя ArrayLists? - PullRequest
77 голосов
/ 28 мая 2009

У меня есть два ArrayList.

ArrayList A содержит

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

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

Я должен сравнить ArrayLst A и ArrayLst B. Результат ArrayList должен содержать список, который не существует в ArrayList A. Результат ArrayList должен быть

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

как сравнить?

Ответы [ 10 ]

187 голосов
/ 28 мая 2009

В 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);

Приведенный выше код выдаст следующий вывод:

First List: [apple, orange]
Second List: [apple, orange, banana, strawberry]
Result: [banana, strawberry]
20 голосов
/ 28 мая 2009

У вас уже есть правильный ответ. А если вы хотите сделать более сложные и интересные операции между списками (коллекциями), используйте коллекции Apache Commons ( CollectionUtils ) Это позволяет вам создавать конъюнкцию / дизъюнкцию, находить пересечения, проверять, является ли одна коллекция подмножеством другой, и другие полезные вещи.

11 голосов
/ 07 ноября 2017

В 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());

Обратите внимание, что хэш-набор создается только один раз: ссылка на метод привязана к его содержащему методу. Чтобы сделать то же самое с лямбдой, нужно было бы иметь набор в переменной. Создание переменной не является плохой идеей, особенно если вы считаете ее неприглядной или трудной для понимания.

Вы не можете легко отрицать предикат без чего-либо подобного этому вспомогательному методу (или явному приведению), так как вы не можете напрямую вызвать ссылку на метод отрицания (сначала необходимо определить тип). *

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

Если бы у потоков был метод filterOut или что-то подобное, это выглядело бы лучше.

9 голосов
/ 28 мая 2009

РЕДАКТИРОВАТЬ: Оригинальный вопрос не указан язык. Мой ответ на C #.

Вместо этого вы должны использовать HashSet. Если вы должны использовать ArrayList, вы можете использовать следующие методы расширения:

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

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

используя 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
7 голосов
/ 11 октября 2016

Хотя это очень старый вопрос в 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());
7 голосов
/ 02 сентября 2014

Я использовал гуаву Sets.difference .

Параметры - это наборы, а не общие коллекции, но удобный способ создания наборов из любой коллекции (с уникальными элементами) - это Guava ImmutableSet.copyOf (Iterable).

(я впервые опубликовал это на связанном / двойном вопросе , но я также копирую его и здесь, так как считаю, что это хороший вариант, которого пока не хватает.)

2 голосов
/ 28 мая 2009

Полагаю, вы говорите о 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;
    }
1 голос
/ 07 марта 2016

ЭТА РАБОТА ТАКЖЕ С 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 голос
/ 07 марта 2014

Привет, используйте этот класс, он сравнит оба списка и покажет точное несовпадение ч / б обоих списков.

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 голос
/ 28 мая 2009

Вы просто сравниваете строки.

Поместите значения в ArrayList A в качестве ключей в HashTable A.
Поместите значения в ArrayList B в качестве ключей в HashTable B.

Затем для каждого ключа в HashTable A удалите его из HashTable B, если он существует.

В HashTable B остались те строки (ключи), которые не были значениями в ArrayList A.

Пример 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>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...