Есть ли лучший способ объединить два набора строк в java? - программирование
Подтвердить что ты не робот

Есть ли лучший способ объединить два набора строк в java?

Мне нужно объединить два набора строк при фильтрации избыточной информации, это решение, с которым я столкнулся, есть ли лучший способ, который может предложить любой человек? Возможно, что-то построенное в том, что я забыл? Не повезло с Google.

Set<String> oldStringSet = getOldStringSet();
Set<String> newStringSet = getNewStringSet();

for(String currentString : oldStringSet)
{
    if (!newStringSet.contains(currentString))
    {
        newStringSet.add(currentString);
    }
}
4b9b3361

Ответ 1

Так как a Set не содержит повторяющихся записей, вы можете объединить их двумя:

newStringSet.addAll(oldStringSet);

Не имеет значения, если вы добавляете вещи дважды, набор будет содержать только один элемент... например, нет необходимости проверять с помощью метода contains.

Ответ 2

Вы можете сделать это, используя эту однострочную

Set<String> combined = Stream.concat(newStringSet.stream(), oldStringSet.stream())
        .collect(Collectors.toSet());

При статическом импорте это выглядит еще лучше

Set<String> combined = concat(newStringSet.stream(), oldStringSet.stream())
        .collect(toSet());

Другой способ - использовать метод flatMap:

Set<String> combined = Stream.of(newStringSet, oldStringSet).flatMap(Set::stream)
        .collect(toSet());

Также любая коллекция может быть легко объединена с одним элементом

Set<String> combined = concat(newStringSet.stream(), Stream.of(singleValue))
        .collect(toSet());

Ответ 3

То же самое с гуавой:

Set<String> combinedSet = Sets.union(oldStringSet, newStringSet)

Ответ 4

Из определения Set содержат только уникальные элементы.

Set<String> distinct = new HashSet<String>(); 
 distinct.addAll(oldStringSet);
 distinct.addAll(newStringSet);

Чтобы улучшить код, вы можете создать общий метод для этого

public static <T> Set<T> distinct(Collection<T>... lists) {
    Set<T> distinct = new HashSet<T>();

    for(Collection<T> list : lists) {
        distinct.addAll(list);
    }
    return distinct;
}

Ответ 5

Просто используйте newStringSet.addAll(oldStringSet). Нет необходимости проверять дубликаты, как это делает реализация Set.

Ответ 7

 newStringSet.addAll(oldStringSet);

Это приведет к соединению s1 и s2

Ответ 8

Set.addAll()

Добавляет все элементы в указанной коллекции к этому набору, если они еще не присутствуют (дополнительная операция). Если указанная коллекция также является набором, операция addAll эффективно изменяет этот набор так, чтобы его значение было объединением двух наборов

newStringSet.addAll(oldStringSet)

Ответ 9

Использовать boolean addAll(Collection<? extends E> c)
Добавляет все элементы в указанной коллекции к этому набору, если они еще не присутствуют (дополнительная операция). Если указанная коллекция также является набором, операция addAll эффективно изменяет этот набор так, чтобы его значение было объединением двух наборов. Поведение этой операции undefined, если указанная коллекция изменяется во время выполнения операции.

newStringSet.addAll(oldStringSet)

Ответ 10

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

Set<String> newStringSet = getNewStringSet();
Set<String> oldStringSet = getOldStringSet();

Set<String> myResult;
if(oldStringSet.size() > newStringSet.size()){
    oldStringSet.addAll(newStringSet);
    myResult = oldStringSet;
} else{
    newStringSet.addAll(oldStringSet);
    myResult = newStringSet;
}

Таким образом, если в вашем новом наборе 10 элементов, а в старом наборе 100 000, вы выполняете только 10 операций вместо 100 000.

Ответ 11

Если вы используете Guava, вы также можете использовать конструктор для большей гибкости:

ImmutableSet.<String>builder().addAll(someSet)
                              .addAll(anotherSet)
                              .add("A single string")
                              .build();