Подтвердить что ты не робот

Как я могу рассчитать разницу между двумя ArrayLists?

У меня есть два списка ArrayLists.

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

В 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 или что-то подобное, это выглядело бы лучше.


Кроме того, @Holger дал мне идею. ArrayList имеет метод removeAll, оптимизированный для многократных удалений, он только один раз переставляет свои элементы. Однако он использует метод contains, предоставляемый данной коллекцией, поэтому нам нужно оптимизировать эту часть, если listA совсем не крошечный.

С ранее объявленными listA и listB этому решению не требуется Java 8, и он очень эффективен.

List<String> result = new ArrayList(listB);
result.removeAll(new HashSet<>(listA));

Ответ 4

EDIT: Исходный вопрос не указал язык. Мой ответ на С#.

Вместо этого вы должны использовать 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

Ответ 5

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

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

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

Ответ 6

Хотя это очень старый вопрос в 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

Я думаю, вы говорите о С#. Если это так, вы можете попробовать это

    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

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

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

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

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

Пример С# (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

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

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

ЭТА РАБОТА ТАКЖЕ С 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);