У меня есть два набора, A и B, одного типа.
Я должен найти, содержит ли A какой-либо элемент из множества B.
Что было бы лучшим способом сделать это без перебора наборов? В библиотеке Set есть contains(object)
и containsAll(collection)
, но нет containsAny(collection)
.
Ответы:
Не
Collections.disjoint(A, B)
сработает? Из документации:Таким образом, метод возвращает,
false
если коллекции содержат какие-либо общие элементы.источник
Stream::anyMatch
С Java 8 вы можете использовать
Stream::anyMatch
.источник
anyMatch
будет транслировать все элементыsetA
и вызывать ихsetB.contains()
все. Если «true» возвращается для любого из элементов, выражение в целом будет иметь значение true. Надеюсь, это помогло.Хороший способ реализовать containsAny для множеств - использовать Guava Sets.intersection () .
containsAny
вернул быboolean
, поэтому вызов выглядит так:Это возвращает истину, если множества не пересекаются, иначе ложь. Временная сложность этого, вероятно, немного лучше, чем retainAll, потому что вам не нужно делать клонирование, чтобы избежать изменения вашего исходного набора.
источник
У Apache Commons есть метод
CollectionUtils.containsAny()
.источник
Я использую org.apache.commons.collections.CollectionUtils
Вот и все! Возвращает true, если хотя бы один элемент находится в обеих коллекциях.
Прост в использовании, а название функции более наглядно.
источник
Используйте
retainAll()
в интерфейсе Set. Этот метод обеспечивает пересечение элементов, общих в обоих наборах. См. API документы для получения дополнительной информации.источник
retainAll
вероятно, не поможет. Его реализация вAbstractCollection
итерациях.O(1)
выполнения в лучшем случае, в то время какretainAll
будет иметь что-то подобноеO(N)
(это будет зависеть от размера только 1 набора) лучшее время выполнения.Я бы порекомендовал создать
HashMap
из набора A, а затем выполнить итерацию по набору B и проверить, есть ли какой-либо элемент B в A. Это будет выполняться воO(|A|+|B|)
времени (так как не будет столкновений), тогда какretainAll(Collection<?> c)
должно выполняться воO(|A|*|B|)
времени.источник
Есть немного грубый способ сделать это. Если и только если набор A содержит некоторый элемент B, чем вызов
изменит набор А. В этом случае removeAll вернет true (как указано в документации по removeAll ). Но, вероятно, вы не хотите изменять набор A, поэтому вы можете подумать, что будете действовать с копией, вот так:
и возвращаемое значение будет истинным, если множества не различны, то есть они имеют непустое пересечение.
Также см. Коллекции Apache Commons
источник
Вы можете использовать метод retainAll и получить пересечение двух ваших множеств.
источник
retainAll
его использования необходимо сделать копию исходного набора. Тогда это более эффективно для использования,HashSet
как предлагает Зейчин .