Java: сравнение двух строковых массивов и удаление элементов, которые существуют в обоих массивах - PullRequest
13 голосов
/ 05 августа 2009

Это в основном вопросы производительности. У меня есть основной список всех пользователей, существующих в массиве строк AllUids. У меня также есть список всех конечных пользователей, существующих в массиве строк 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"}

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

Ответы [ 7 ]

13 голосов
/ 05 августа 2009

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

Collection removeAll(Collection collection,
                     Collection remove)

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

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

РЕДАКТИРОВАТЬ: Я также немного покопался в коллекциях Commons и нашел следующее решение с ListUtils в коллекциях Commons:

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

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

6 голосов
/ 05 августа 2009

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

Вы могли бы использовать 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);

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

4 голосов
/ 09 ноября 2010
/*
 * 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);
        }
    }
}
3 голосов
/ 05 августа 2009

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

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

3 голосов
/ 05 августа 2009

Самое простое решение, вероятно, состоит в том, чтобы поместить все элементы в Set, а затем использовать removeAll. Вы можете преобразовать в Set из массива, как это:

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

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

1 голос
/ 05 августа 2009

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

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