Что-то вроде "содержит любые" для набора Java?

У меня есть два набора, 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. Сложность этого времени, вероятно, немного лучше, чем удержание, потому что вам не нужно делать клонирование, чтобы избежать изменения исходного набора.

Ответ 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