Как проверить две коллекции на случай игнорирования равенства? - PullRequest
0 голосов
/ 26 февраля 2019

Я хочу обрабатывать строчные и прописные значения одинаково и убедиться, что две коллекции равны (не нужно сортировать)

Это моя реализация:

private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2)
{
    Set<String> s1 = new HashSet<>();
    c1.forEach(i -> s1.add(i.toLowerCase()));

    Set<String> s2 = new HashSet<>();
    c2.forEach(i -> s2.add(i.toLowerCase()));

    return s1.size() == s2.size() && s2.containsAll(s1);
}

Есть ли более простой способ сделать это?Или лучше иметь свой метод

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Ваше реальное решение очень приемлемо.Это достаточно ясно и должно иметь в целом хорошую производительность.

Вы должны использовать Set.equals() вместо Set.containsAll().Он делает то же самое, но избавляет вас от сравнения размера с оптимизацией.

1) Потоковая версия вашего кода может быть:

private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2) {
    return c1.stream()
             .map(String::toLowerCase)
             .collect(toSet())
             .equals(c2.stream()
                       .map(String::toLowerCase)
                       .collect(toSet()));
}

2) Вот второй вариант с Treeset.
Я не уверен, что это проще, ноон избегает явных циклов и делает логику более явной, чем факторизованная:

private boolean stringCollectionEqualsIgnoreCase(Collection<String> c1, Collection<String> c2)
{
    Comparator<String> comp = Comparator.comparing(String::toLowerCase);
    Set<String> s1 = new TreeSet<>(comp);
    Set<String> s2 = new TreeSet<>(comp);
    s1.addAll(c1);
    s2.addAll(c2);
    return s1.equals(s2);
}

Обратите внимание, что он удаляет дубликаты в соответствии с компаратором.Это означает, что это сортирует.Так что это может быть медленнее или быстрее, чем ваше реальное решение в зависимости от ситуации.Конечно, для небольших Set с не имеет значения.

0 голосов
/ 26 февраля 2019

Если реализации, которая работает с Set s, достаточно, вы можете сохранить свои уникальные элементы в TreeSet с помощью специального нечувствительного к регистру компаратора:

Set<String> uniqueStrings = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

Таким образом, вы можете сделатьсравнение просто с uniqueStrings.equals(anotherTreeSet).Это что-то вроде хака, я должен признать.

0 голосов
/ 26 февраля 2019

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

public boolean containsAllIgnoreCase(Collection<String> var1, Collection<String> var2) {
    return var1.stream()
               .map(String::toLowerCase)
               .collect(toList())
               .containsAll(var2.stream()
                                .map(String::toLowerCase)
                                .collect(toList());
}

Илиеще проще читать

public List<String> toLowerCaseList(Collection<String> var) {
    return var.stream().map(String::toLowerCase).toList();
}

public boolean containsAllIgnoreCase(Collection<String> var1, Collection<String> var2) {
    return toLowerCaseList(var1).containsAll(toLowerCaseList(var2));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...