Вопросы для собеседования по Java (серия) — потоки

Все еще использую for петли? Возможно, пришло время для чего-то нового!

Говоря о Функциональные интерфейсы и Лямбда-выраженияэто правильно, что мы продолжаем нашу серию, говоря о Потоки.

Еще одна важная новая функция, появившаяся в Java 8, — это Stream функциональность.

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

Как вы, наверное, заметили из других постов, я не из тех, кто говорит только о теории.

Давайте посмотрим, как они играют, и поймем, как они работают. 🚀

Выполнение

💈 Лучшая аналогия для потоков — это pipe, так это на самом деле упоминается в некоторых местах. В этой трубе у вас есть elements приходят по одному.

🔵 Инициализация потоков

Существует несколько способов создания и инициализации потоков.

🔹 Пустой поток

Stream<Integer> emptyStream = Stream.empty();

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

Например, вы можете ознакомиться с ofNullable метод на Stream сорт. Вторая часть не имеет большого значения, здесь вы можете увидеть, как пустой Stream может быть использован.

public static<T> Stream<T> ofNullable(T t) {
        return t == null ? Stream.empty()
                         : StreamSupport.stream(new Streams.StreamBuilderImpl<>
}

Stream.java

🔹 Поток.строитель()

Stream<Integer> streamUsingBuilder = Stream.<Integer>builder()
                .add(1234)
                .build();

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

🔹 Поток()

Stream<Integer> stringStream = Stream.of(1, 2, 3, 4, 5);

Вы также можете инициализировать поток inline, используя static of метод.

🔹 Массивы.stream()

Вы можете создать поток из массива, используя java.util.Arrays сорт.

Integer[] intArray = new Integer[] {1,2,3,4,5};
        
Stream<Integer> intStream = Arrays.stream(intArray);

🔹 Коллекции.поток()

Collection интерфейс получил новый метод взаимодействия с недавно добавленным Stream сорт.

Благодаря этому любой объект, реализующий этот интерфейс, может быть преобразован в поток с помощью stream() метод.

List<Integer> intList = new ArrayList<>();
Stream<Integer> intStreamFromList = intList.stream();
Set<Integer> intSet = new HashSet<>();
Stream<Integer> intStreamFromSet = intSet.stream();

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

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

Посмотрите больше подобных сообщений на new-spike.net

Пока они в трубе, вы можете:

🔸 изменить свое состояние

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stringStream = integerStream.map(val -> "Element: " + val); // Element: 1, Element: 2, Element: 3, Element: 4, Element: 5
Stream<Stream<Integer>> streamOfStreams = Stream.of(Stream.of(1), Stream.of(2,3), Stream.of(4,5,6));
Stream<String> integerStreams = streamsOfStreams.flatMap(val -> "Element: " + val); // Element: 1, Element: 2, Element: 3, Element: 4, Element: 5, Element: 6

🔸 отфильтровать некоторые из них

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
integerStream.filter(val -> val%2 == 0); // 2, 4

🔸 пропустить некоторые элементы

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
integerStream.skip(4) // 5

🔸 сортировать элементы

Stream<Integer> integerStream = Stream.of(3, 2, 1, 4, 5);
integerStream.sorted(); // 1, 2, 3, 4, 5

🔸 применять побочные эффекты

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
integerStream.peek(val -> System.out.println("Element: " + val)); // Element: 1, Element: 2, Element: 3, Element: 4, Element: 5

🔵 Терминальные операции

В конце трубы вы можете:

🔸 собрать элементы в другой набор данных

Stream<Integer> integerStream = Stream.of(1, 2, 1, 2, 1);        
integerStream.collect(Collectors.toSet()); // 1, 2

🔸 вернуть один результат

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
Integer sum = integerStream.reduce(0, (a, b) -> a+b); // 15
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
Optional<Integer> result = integerStream.findFirst(); // Optional.of(1)

🔸 вернуть недействительным

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
integerStream.forEach(val -> System.out.println("Element: " + val)); // Element: 1, Element: 2, Element: 3, Element: 4, Element: 5

❗️ В потоке промежуточные операции «ленивы».

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

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

Посмотрите больше подобных сообщений на new-spike.net

🔵 Закрытие стримов

Streams реализовать AutoCloseable интерфейс, это означает, что они реализуют close() метод.

❗️ Вы должны быть осторожны при закрытии потока, потому что после закрытия он выдаст IllegalStateException если вы попытаетесь оперировать его снова.

Обычно вам не нужно закрывать потоки, так как их источники collections или arrays которые не требуют специального управления ресурсами.

❗️ Единственное исключение может быть, когда вы оперируете IO ресурсы, такие как поток строк File. Этот вариант использования потребует закрытия потока. ❗️

✅ Чтобы сделать это самым чистым способом, вы должны открыть поток в try-with-resources блок, который будет автоматически обрабатывать закрытие потока после завершения всех операций.

Не пропустите больше таких сообщений! Подпишитесь на нашу бесплатную рассылку новостей!

В настоящее время я работаю над Java-интервью электронная книга, предназначенная для того, чтобы успешно пройти любое техническое собеседование по Java, которое вы можете пройти.
Следите за обновлениями! 🚀

Посмотрите больше подобных сообщений на new-spike.net

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *