Рубрики
Без рубрики

Java Null-Безопасные потоки из коллекций

Узнайте, как создать поток, защищенный от нуля, из данной коллекции.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы рассмотрим, как создавать безопасные для нуля потоки из коллекций Java.

Для начала необходимо некоторое знакомство со ссылками на методы Java 8, лямбда-выражениями, Необязательными и потоковым API, чтобы полностью понять этот материал.

Если вы не знакомы с какой-либо из этих тем, пожалуйста , сначала ознакомьтесь с нашими предыдущими статьями: Новые функции в Java 8, Руководство по Java 8 Необязательно и Введение в потоки Java 8 .

2. Зависимость Maven

Прежде чем мы начнем, есть одна зависимость Maven, которая нам понадобится для определенных сценариев:


    org.apache.commons
    commons-collections4
    4.2

Библиотеку commons-collections4 можно загрузить из Maven Central.

3. Создание потоков из коллекций

Основной подход к созданию Потока из любого типа Коллекции заключается в вызове методов stream() или parallelStream() в коллекции в зависимости от типа требуемого потока:

Collection collection = Arrays.asList("a", "b", "c");
Stream streamOfCollection = collection.stream();

Наша коллекция, скорее всего, будет иметь внешний источник в какой-то момент, мы, вероятно, в конечном итоге получим метод, аналогичный приведенному ниже, при создании потоков из коллекций:

public Stream collectionAsStream(Collection collection) {
    return collection.stream();
}

Это может вызвать некоторые проблемы. Когда предоставленная коллекция указывает на ссылку null , код вызовет исключение NullPointerException во время выполнения.

В следующем разделе рассматривается, как мы можем защититься от этого.

4. Обеспечение нулевой Безопасности Созданных Потоков Коллекций

4.1. Добавьте проверки для предотвращения разыменования Null

Чтобы предотвратить непреднамеренные null исключения указателей, мы можем добавить проверки для предотвращения null ссылок при создании потоков из коллекций:

Stream collectionAsStream(Collection collection) {
    return collection == null 
      ? Stream.empty() 
      : collection.stream();
}

Однако у этого метода есть несколько проблем.

Во-первых, проверка null мешает бизнес-логике, снижая общую читабельность программы.

Во-вторых, использование null для представления отсутствия значения считается неправильным подходом после Java SE 8: есть лучший способ смоделировать отсутствие и наличие значения.

Важно иметь в виду, что пустая Коллекция – это не то же самое, что null | Коллекция . В то время как первый из них указывает на то, что в нашем запросе нет результатов или элементов для отображения, второй предполагает, что во время процесса просто произошла какая-то ошибка.

4.2. Используйте метод emptyIfNull из библиотеки CollectionUtils

Мы можем использовать библиотеку CollectionUtils Apache Commons, чтобы убедиться, что наш поток null безопасен. Эта библиотека предоставляет метод emptyIfNull , который возвращает неизменяемую пустую коллекцию, заданную в качестве аргумента null , или саму коллекцию в противном случае:

public Stream collectionAsStream(Collection collection) {
    return emptyIfNull(collection).stream();
}

Это очень простая стратегия. Однако это зависит от внешней библиотеки. Если политика разработки программного обеспечения ограничивает использование такой библиотеки, то это решение становится нулевым и недействительным.

4.3. Используйте дополнительные функции Java 8

Java SE 8 Необязательно -это контейнер с одним значением, который либо содержит значение, либо нет. Если значение отсутствует, контейнер Optional считается пустым.

Использование Необязательно можно, пожалуй, рассматривать как лучшую общую стратегию для создания коллекции nullsafecollection из потока.

Давайте посмотрим, как мы можем его использовать, а затем кратко обсудим ниже:

public Stream collectionToStream(Collection collection) {
    return Optional.ofNullable(collection)
      .map(Collection::stream)
      .orElseGet(Stream::empty);
}
  • Необязательный.ofNullable(коллекция) создает Необязательный объект из переданной коллекции. Пустой Необязательный объект создается, если коллекция имеет значение null.
  • map(Collection::stream) извлекает значение, содержащееся в Необязательном объекте, в качестве аргумента метода map ( Collection.stream() )
  • или же Get(Stream::empty) возвращает запасное значение в том случае, если Необязательный объект пуст, т. е. переданная коллекция является null .

В результате мы активно защищаем наш код от непреднамеренных исключений null указателей.

4.4. Используйте поток Java 9 из Nullable

Рассматривая наш предыдущий троичный пример в разделе 4.1. и учитывая возможность того , что некоторые элементы могут быть null вместо Коллекции , мы имеем в нашем распоряжении метод ofNullable в классе Stream .

Мы можем преобразовать приведенный выше образец в:

Stream collectionAsStream(Collection collection) {  
  return collection.stream().flatMap(s -> Stream.ofNullable(s));
}

5. Заключение

В этой статье мы кратко рассмотрим, как создать поток из данной коллекции. Затем мы приступили к изучению трех ключевых стратегий для обеспечения безопасности созданного потока при создании из коллекции.

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

Как обычно, полный исходный код, сопровождающий статью, доступен на GitHub .