Set.isEmpty(): примеры (JAVA)

Разбор метода isEmpty() для коллекций Set в Java
Раздел: Коллекции, Set
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 в многопоточной среде и риск гонки

Пример java
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()

Пример java
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 и библиотек

Пример java
import java.util.*;

Set<String> maybe = null;
boolean empty = Optional.ofNullable(maybe).map(Set::isEmpty).orElse(true);
System.out.println(empty);
true

Альтернатива с Apache Commons:

Пример java
import org.apache.commons.collections4.CollectionUtils;

Set<String> maybe = null;
System.out.println(CollectionUtils.isEmpty(maybe));
true

4) Проверка наличия элементов без вычисления размера: iterator().hasNext()

Пример java
Set<String> s = someLargeLazySet();
boolean hasAny = s.iterator().hasNext();
System.out.println(!hasAny);
// true или false, но iterator().hasNext() может быть дешевле, чем size()

5) Использование в потоках Stream API

Пример java
Set<Integer> s = Set.of(1, 2, 3);
boolean empty = s.stream().findAny().isEmpty();
System.out.println(empty);
false

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

джава Set.isEmpty() function comments

En
Set.isEmpty() Проверяет, пуст ли набор