← Назад к вопросам

Как получить единственный элемент из списка типа List?

2.0 Middle🔥 191 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Получение единственного элемента из List

Вот несколько способов, от базовых до продвинутых.

1. Базовый способ: get(0)

Самый простой, если ты уверен, что элемент существует:

List<String> items = Arrays.asList("only");
String item = items.get(0);
System.out.println(item);  // "only"

⚠️ Опасно: если список пуст, будет IndexOutOfBoundsException.

2. Проверка размера перед получением

Безопаснее:

List<String> items = new ArrayList<>();
items.add("value");

if (items.size() == 1) {
    String item = items.get(0);
    System.out.println(item);
} else {
    System.out.println("Список не содержит ровно один элемент!");
}

3. Optional.get() для элемента

Если тебе нужна работа с потенциально отсутствующим элементом:

List<String> items = new ArrayList<>();
items.add("value");

Optional<String> item = items.stream().findFirst();
if (item.isPresent()) {
    System.out.println(item.get());
} else {
    System.out.println("Список пуст!");
}

// Или короче с ifPresent
items.stream().findFirst().ifPresent(System.out::println);

4. Stream.findFirst() (для поиска одного)

Если ты ищешь ОДИН элемент по условию:

List<User> users = Arrays.asList(
    new User(1, "Alice"),
    new User(2, "Bob")
);

Optional<User> user = users.stream()
    .filter(u -> u.getId() == 2)
    .findFirst();

user.ifPresent(u -> System.out.println(u.getName()));  // "Bob"

5. Stream.findAny() (для параллельных потоков)

Если работаешь с параллельными потоками:

Optional<String> item = items.parallelStream()
    .findAny();

item.ifPresent(System.out::println);

6. Проверка на единственность

Если нужно убедиться, что элемент РОВНО ОДИН:

// ❌ Медленно: проверяет весь список
if (items.size() == 1) {
    String item = items.get(0);
}

// ✅ Лучше: останавливается на 2-м элементе
Optional<String> item = items.stream()
    .limit(2)  // Берём максимум 2 для проверки
    .collect(toSingleOptional());  // Утилита ниже

Утилита для проверки единственности:

public static <T> Collector<T, ?, Optional<T>> toSingleOptional() {
    return Collectors.collectingAndThen(
        Collectors.toList(),
        list -> {
            if (list.size() != 1) {
                return Optional.empty();
            }
            return Optional.of(list.get(0));
        }
    );
}

// Использование
Optional<String> unique = items.stream()
    .filter(s -> s.length() > 5)
    .collect(toSingleOptional());

unique.ifPresent(System.out::println);

7. Google Guava: Iterables.getOnlyElement()

Если используешь Guava:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.0.0-jre</version>
</dependency>
import com.google.common.collect.Iterables;

List<String> items = Arrays.asList("only");

// Выбросит исключение, если размер != 1
String item = Iterables.getOnlyElement(items);
System.out.println(item);  // "only"

// Или с дефолтным значением
String itemOrDefault = Iterables.getOnlyElement(items, "default");

Это очень удобно для asserts в тестах!

8. Apache Commons Lang

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>
import org.apache.commons.lang3.CollectionUtils;

List<String> items = Arrays.asList("only");

if (CollectionUtils.isNotEmpty(items) && items.size() == 1) {
    String item = items.get(0);
}

9. Практический пример: получить автора

public class Article {
    private String title;
    private List<Author> authors;

    // Получить автора, если он один
    public Optional<Author> getSingleAuthor() {
        return authors.stream()
            .collect(toSingleOptional());
    }

    // Или с Guava
    public Author getSingleAuthorGuava() throws IllegalArgumentException {
        return Iterables.getOnlyElement(authors);
    }
}

Использование:

Article article = new Article();
article.getSingleAuthor()
    .ifPresent(author -> System.out.println("Author: " + author.getName()));

10. Сравнение подходов

МетодКогда использоватьПлюсыМинусы
get(0)Уверен, есть элементПростойОпасен (исключение)
size() == 1 && get(0)Нужна проверкаБезопасныйМногословный
findFirst()Stream с фильтромУдобныйНужен Optional
toSingleOptional()Нужна гарантия единственностиПроверяет размерНужна утилита
Guava.getOnlyElement()Production кодОчень удобныйВнешняя зависимость

11. Типичная ошибка на собеседовании

// ❌ ПЛОХО: может быть IndexOutOfBoundsException
List<String> result = database.query(...);
String value = result.get(0);  // Crash если результат пуст!

// ✅ ПРАВИЛЬНО: проверка
List<String> result = database.query(...);
if (result.isEmpty()) {
    throw new IllegalStateException("No result found");
}
String value = result.get(0);

// ✅ ИЛИ ещё лучше: Optional
Optional<String> value = result.stream().findFirst();
String result = value.orElseThrow(() -> 
    new IllegalStateException("No result found")
);

Чеклист

  • Проверяю, может ли список быть пуст
  • Использую Optional для безопасности
  • Знаю про Guava.getOnlyElement() для unit тестов
  • Знаю, когда нужна гарантия единственности
  • Не игнорирую IndexOutOfBoundsException

Вывод: выбирай между size()==1 && get(0) для простых случаев, findFirst().orElseThrow() для потоков, или Guava.getOnlyElement() для production кода с гарантией единственности.

Как получить единственный элемент из списка типа List? | PrepBro