У меня есть два набора, A и B того же типа.
Мне нужно найти, если A содержит любой элемент из множества B.
Каким будет лучший способ сделать это без итерации над наборами?
Библиотека Set имеет contains(object)
и containsAll(collection)
, но не containsAny(collection)
.
Ответ 1
Не работает Collections.disjoint(A, B)
? Из документации:
Возвращает true
, если две указанные коллекции не имеют общих элементов.
Таким образом, метод возвращает false
, если коллекции содержат какие-либо общие элементы.
Ответ 2
Так как Java 8: setA.stream().anyMatch(setB::contains)
Ответ 3
Хороший способ реализации containsAny для наборов использует Guava Sets.intersection().
containsAny
возвращает boolean
, поэтому вызов выглядит так:
Sets.intersection(set1, set2).isEmpty()
Это возвращает true, если множества не пересекаются, в противном случае - false. Сложность этого времени, вероятно, немного лучше, чем удержание, потому что вам не нужно делать клонирование, чтобы избежать изменения исходного набора.
Ответ 4
Apache Commons имеет метод CollectionUtils.containsAny()
.
Ответ 5
Используйте retainAll()
в интерфейсе Set. Этот метод обеспечивает пересечение элементов, общих в обоих наборах. Дополнительную информацию см. В документах API.
Ответ 6
Я использую org.apache.commons.collections.CollectionUtils
CollectionUtils.containsAny(someCollection1, someCollection2)
Это все!
Возвращает true, если хотя бы один элемент находится в обеих коллекциях.
Прост в использовании, и имя функции более наводящее.
Ответ 7
Вы можете использовать retainAll и получить пересечение двух ваших наборов.
Ответ 8
Я бы рекомендовал создать HashMap
из набора A, а затем выполнить итерацию через множество B и проверить, находится ли какой-либо элемент из B в A. Это будет выполняться в O(|A|+|B|)
времени (поскольку не было бы столкновений), тогда как retainAll(Collection<?> c)
должен выполняться в O(|A|*|B|)
времени.
Ответ 9
Там немного грубый метод для этого.
Если и только если набор A содержит некоторый элемент B, чем вызов
A.removeAll(B)
изменит набор A. В этой ситуации removeAll вернет true (как указано в removeAll docs). Но, вероятно, вы не хотите изменять набор A, чтобы вы могли думать о копировании, например:
new HashSet(A).removeAll(B)
и возвращаемое значение будет истинным, если множества не различны, то есть они имеют непустое пересечение.
Также см. Коллекции сообщества Apache