Set.isEmpty(): примеры (JAVA)
Set.isEmpty(): booleanОписание метода isEmpty()
Метод isEmpty() принадлежит интерфейсу java.util.Collection и широко используется для проверки, содержит ли коллекция элементы. Для множеств (java.util.Set) этот метод возвращает true, когда в наборе нет элементов, и false в противном случае.
Сигнатура метода в интерфейсе Collection:
boolean isEmpty()
Аргументы: метод не принимает аргументов.
Возвращаемое значение: логическое значение true или false. В большинстве реализаций реализация метода эквивалентна проверке size() == 0. В базовой абстракции AbstractCollection метод реализован как:
public boolean isEmpty() {
return size() == 0;
}
Поведение и особенности:
- Вызов на ссылке
nullприводит кNullPointerException. - В типичных реализациях (например,
HashSet) операция выполняется за постоянное время. Однако у некоторых пользовательских или специализированных реализаций сложность может отличаться, если методsize()дорогой. - В многопоточной среде значение может измениться сразу после проверки; метод не даёт атомарной гарантии отсутствия элементов в дальнейшем. Для атомарных проверок и действий требуются дополнительные механизмы синхронизации.
- Некоторые утилиты (например, Apache Commons) предоставляют версии, безопасно обрабатывающие
null(возвращаютtrue, если ссылка равнаnull).
Простые примеры использования
Несколько коротких сценариев с кодом и ожидаемыми результатами.
Пустой HashSet
import java.util.HashSet;
import java.util.Set;
public class Ex1 {
public static void main(String[] args) {
Set s = new HashSet<>();
System.out.println(s.isEmpty());
}
}
true
Набор с элементами
Set s = new HashSet<>();
s.add(10);
System.out.println(s.isEmpty());
false
Проверка при получении коллекции из метода
Set s = Set.of("a", "b");
System.out.println(s.isEmpty());
false
Вызов на null (пример с ошибкой)
Set s = null;
System.out.println(s.isEmpty());
Exception in thread "main" java.lang.NullPointerException
at Ex.main(Ex.java:...)Похожие методы в Java
Короткое сравнение подходов и альтернатив внутри экосистемы Java.
- size() == 0: эквивалент для большинства реализаций; иногда применяется напрямую. При реализации, где
size()дорогой, использование явной реализацииisEmpty()может быть предпочтительнее, если поставщик переопределил его более эффективно. - !collection.iterator().hasNext(): полезно для ленивых или потоковых реализаций, когда не требуется полное вычисление размера и хочется узнать только наличие первого элемента.
- Apache Commons CollectionUtils.isEmpty(collection): безопасно обрабатывает
null(возвращаетtrue, если ссылка равнаnullили коллекция пуста). Удобно для кодовой базы, где часто встречаются nullable коллекции. - Guava Iterables.isEmpty(iterable): проверяет итерабельность; полезно, если объект не реализует
Collection, но поддерживает итерацию.
Выбор зависит от требований к безопасности от null, производительности и типа коллекции.
Аналоги в других языках
Краткие сопоставления с примерами кода и результатами.
JavaScript (Set)
const s = new Set();
console.log(s.size === 0);
true
Python (set)
s = set()
print(len(s) == 0)
# или
print(not s)
True True
PHP (array как набор, или SplObjectStorage/DS");
$arr = [];
var_dump(empty($arr));
// или для коллекций
$set = new SplObjectStorage();
var_dump(count($set) === 0);
bool(true) bool(true)
C# (ICollection<T>)
var set = new HashSet<int>();
Console.WriteLine(set.Count == 0);
True
Golang (map или slice)
m := map[string]struct{}{}
fmt.Println(len(m) == 0)
true
Lua (таблица как контейнер)
local t = {}
local empty = next(t) == nil
print(empty)
true
Kotlin (Set)
val s = emptySet<Int>()
println(s.isEmpty())
true
SQL (проверка таблицы на пустоту)
SELECT CASE WHEN EXISTS (SELECT 1 FROM table_name) THEN 0 ELSE 1 END AS is_empty;
-- возвращает 1 если таблица пуста, 0 если есть строки
Отличия от Java: во многих языках нет метода isEmpty у структуры Set, вместо этого используется проверка размера или удобные встроенные функции. В Java удобство в стандартизации через интерфейс Collection и возможность переопределения для оптимизации.
Типичные ошибки и ловушки
Наиболее часто встречающиеся проблемы при использовании isEmpty() с примерами.
1) NullPointerException при вызове на null
Set<String> s = null;
System.out.println(s.isEmpty());
Exception in thread "main" java.lang.NullPointerException
at ...
Решение: проверить на null или использовать утилиты, возвращающие true для null.
2) Ошибочные ожидания в многопоточной среде
Set<Integer> s = ConcurrentHashMap.newKeySet();
// Поток A
if (s.isEmpty()) {
// предполагается, что можно безопасно добавить/прочитать
}
// Между проверкой и действием другой поток может изменить s
// Нет прямого вывода, но логика может быть неверной из-за гонки
Последствие: неверные предположения о состоянии коллекции после проверки; требуется синхронизация или атомарные операции.
3) Неправильные ожидания по производительности
class SlowSet extends HashSet<String> {
public int size() {
// дорогостоящая операция
try { Thread.sleep(100); } catch (InterruptedException e) {}
return super.size();
}
}
Set<String> s = new SlowSet();
System.out.println(s.isEmpty());
true // но вызов может быть медленным
Вывод: проверить документацию реализации, если важна производительность.
Изменения в методе в версиях Java
Метод isEmpty() объявлен в интерфейсе Collection с ранних версий Java (начиная с Java 1.2), а стандартная реализация в AbstractCollection использует size() == 0. В последних версиях языка сам метод не претерпевал значимых изменений. Основные наблюдаемые изменения касались сопутствующих библиотек и утилит (например, добавление утилит в сторонних библиотеках и улучшения многопоточных коллекций), но сигнатура и семантика метода остались прежними.
Расширенные и нетипичные примеры
Несколько подробных сценариев, включая многопоточные примеры, оптимизацию и использование утилит.
1) Использование isEmpty в многопоточной среде и риск гонки
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class Race {
public static void main(String[] args) throws Exception {
Set<Integer> s = ConcurrentHashMap.newKeySet();
Thread t1 = new Thread(() -> {
if (s.isEmpty()) {
// ожидание, что теперь можно выполнить действие
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
s.add(1);
}
});
Thread t2 = new Thread(() -> {
s.add(2);
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(s);
}
}
[1, 2] // результат непредсказуем, порядок и содержимое зависят от выполнения
Комментарий: проверка isEmpty() не защищает от вмешательства других потоков; для атомарной логики требуется синхронизация или использование специализированных структур.
2) Оптимизация: переопределение isEmpty для дорогого size()
import java.util.AbstractSet;
import java.util.Iterator;
public class FastEmptySet<E> extends AbstractSet<E> {
private boolean hasAny = false;
@Override
public boolean isEmpty() {
// быстрый флаг вместо подсчёта всех элементов
return !hasAny;
}
@Override
public Iterator<E> iterator() { throw new UnsupportedOperationException(); }
@Override
public int size() { return hasAny ? 1 : 0; }
public void addSample() { hasAny = true; }
}
// Использование
FastEmptySet<String> s = new FastEmptySet<>();
System.out.println(s.isEmpty());
s.addSample();
System.out.println(s.isEmpty());
true false
Комментарий: в пользовательских структурах можно реализовать более эффективную проверку пустоты, чем обход или подсчёт всех элементов.
3) Обработка nullable коллекций: использование Optional и библиотек
import java.util.*;
Set<String> maybe = null;
boolean empty = Optional.ofNullable(maybe).map(Set::isEmpty).orElse(true);
System.out.println(empty);
true
Альтернатива с Apache Commons:
import org.apache.commons.collections4.CollectionUtils;
Set<String> maybe = null;
System.out.println(CollectionUtils.isEmpty(maybe));
true
4) Проверка наличия элементов без вычисления размера: iterator().hasNext()
Set<String> s = someLargeLazySet();
boolean hasAny = s.iterator().hasNext();
System.out.println(!hasAny);
// true или false, но iterator().hasNext() может быть дешевле, чем size()
5) Использование в потоках Stream API
Set<Integer> s = Set.of(1, 2, 3);
boolean empty = s.stream().findAny().isEmpty();
System.out.println(empty);
false
Комментарий: в некоторых случаях для ленивых источников проверка через стрим может быть оправдана, но для обычных коллекций это избыточно.