Java: сравнение двух строковых массивов и удаление элементов, существующих в обоих массивах

Это в основном вопросы производительности. У меня есть главный список всех пользователей, существующих в массиве String AllUids. У меня также есть список всех конечных пользователей, существующих в массиве String EndUids.

Я работаю в Java, и моя цель - удалить всех пользователей, которые существуют в конце датированного массива из главного списка AllUids. Я знаю, что PHP имеет функцию array_diff.

Мне было любопытно, есть ли в Java что-нибудь, что сравнит два массива и удалит элементы, похожие на оба. Моя цель - производительность здесь, поэтому я спросил о встроенной функции. Я не хочу добавлять какие-либо специальные пакеты.

Я думал о написании рекурсивной функции, но кажется, что она будет неэффективной. В обоих списках есть тысячи пользователей. Чтобы существовать в конце списка, вы должны существовать в списке AllUids, то есть до удаления.

Пример:

String[] AllUids = {"Joe", "Tom", "Dan", "Bill", "Hector", "Ron"};

String[] EndUids = {"Dan", "Hector", "Ron"};

Функциональность, которую я ищу:

String[] ActiveUids = AllUids.RemoveSimilar(EndUids);

ActiveUids будет выглядеть так:

{"Joe", "Tom", "Bill"}

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

Ответ 1

Коллекции Commons имеет класс под названием CollectionUtils и статический метод, называемый removeAll, который берет начальный список и список вещей, которые нужно удалить из этого списка:

Collection removeAll(Collection collection,
                     Collection remove)

Это должно делать то, что вы хотите, если используете списки пользователей, а не массивы. Вы можете легко преобразовать свой массив в список с помощью Arrays.asList(), поэтому...

Collection ActiveUids = CollectionUtils.removeAll(Arrays.asList(AllUids), 
                                                  Arrays.asList(EndUids))

EDIT: я также немного поработал с этим в Commons Collections и нашел следующее решение с ListUtils в коллекциях Commons:

List diff = ListUtils.subtract(Arrays.asList(AllUids), Arrays.asList(EndUids));

Довольно аккуратный...

Ответ 2

Вы не можете "удалить" элементы из массивов. Вы можете установить их в null, но массивы имеют фиксированный размер.

Вы можете использовать java.util.Set и removeAll, чтобы взять один от другого, но я бы предпочел использовать Библиотека коллекций Google:

Set<String> allUids = Sets.newHashSet("Joe", "Tom", "Dan",
                                      "Bill", "Hector", "Ron");
Set<String> endUids = Sets.newHashSet("Dan", "Hector", "Ron");
Set<String> activeUids = Sets.difference(allUids, endUids);

Это более функциональное чувство.

Ответ 3

Самое простое решение - это, вероятно, поместить все элементы в набор, а затем использовать removeAll. Вы можете преобразовать в набор из массива следующим образом:

Set<String> activeUids = new HashSet<String>(Arrays.asList(activeUidsArray));

хотя вы действительно должны стараться избегать использования массивов и поддержки коллекций.

Ответ 4

Не используйте для этого массивы, используйте метод Collection и removeAll(). Что касается производительности: если вы не делаете что-то идиотское, что приводит к O (n ^ 2) времени выполнения, просто забудьте об этом. Это преждевременная оптимизация, бесполезный/вредный вид. "тысячи пользователей" - это ничего, если вы не делаете это тысячи раз в секунду.

Кстати, PHP "массивы" на самом деле являются хэш-картами.

Ответ 5

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Bireswhar
 */
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Repeated {

    public static void main(String[] args) {
//        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
//        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));
//
//        listOne.retainAll( listTwo );
//        System.out.println( listOne );

        String[] s1 = {"ram", "raju", "seetha"};
        String[] s2 = {"ram"};
        List<String> s1List = new ArrayList(Arrays.asList(s1));
        for (String s : s2) {
            if (s1List.contains(s)) {
                s1List.remove(s);
            } else {
                s1List.add(s);
            }
             System.out.println("intersect on " + s1List);
        }
    }
}

Ответ 6

Вместо этого вы можете поместить эти строки в Collection, а затем использовать метод removeAll.

Ответ 7

    String s1 = "a,b,c,d";
    String s2 = "x,y,z,a,b,c";
    Set<String> set1 = new HashSet<String>();
    Set<String> set2 = new HashSet<String>();

    Set<String> set11 = new HashSet<String>();

    String[] splitS1 = s1.split(",");
    String[] splitS2 = s2.split(",");

    for(String s3:splitS1){
        set1.add(s3);
        set11.add(s3);
    }

    for(String s4:splitS2){
        set2.add(s4);
    }
    set1.removeAll(set2);
    set2.removeAll(set11);
    set1.addAll(set2);
    System.out.println(set1);