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

Как итерировать над потоком с индексами

Узнайте несколько способов итерации потоков Java 8 с помощью индексов

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

1. Обзор

Java 8 Потоки не коллекции и элементы не могут быть доступны с помощью своих индексов, но Есть еще несколько трюков, чтобы сделать это возможным.

В этой короткой статье, мы будем смотреть на то, как итерировать в течение Поток с помощью IntStream, StreamUtils, EntryStream, и Вавр ‘ы Поток .

2. Использование простой Java

Мы можем перемещаться по Поток с помощью Интегер диапазона, а также извлечь выгоду из того факта, что оригинальные элементы находятся в массиве или коллекции, доступной по индексам.

Давайте реализуем метод, который итерирует с индексами и демонстрирует этот подход.

Проще говоря, мы хотим получить массив Струны и выбирают только даже индексные элементы:

public List getEvenIndexedStrings(String[] names) {
    List evenIndexedNames = IntStream
      .range(0, names.length)
      .filter(i -> i % 2 == 0)
      .mapToObj(i -> names[i])
      .collect(Collectors.toList());
    
    return evenIndexedNames;
}

Давайте теперь проверить реализации:

@Test
public void whenCalled_thenReturnListOfEvenIndexedStrings() {
    String[] names 
      = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
    List expectedResult 
      = Arrays.asList("Afrim", "Besim", "Durim");
    List actualResult 
      = StreamIndices.getEvenIndexedStrings(names);
   
    assertEquals(expectedResult, actualResult);
}

3. Использование StreamUtils

Другой способ итерировать с индексами можно сделать с помощью zipWithIndex () метод СтримУтилс из протон-пакет библиотека (последняя версия можно найти здесь ).

Во-первых, вы должны добавить его в свой пом.xml :


    com.codepoetics
    protonpack
    1.13

Теперь давайте посмотрим на код:

public List> getEvenIndexedStrings(List names) {
    List> list = StreamUtils
      .zipWithIndex(names.stream())
      .filter(i -> i.getIndex() % 2 == 0)
      .collect(Collectors.toList());
    
    return list;
}

Следующие тесты этого метода и успешно проходит:

@Test
public void whenCalled_thenReturnListOfEvenIndexedStrings() {
    List names = Arrays.asList(
      "Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim");
    List> expectedResult = Arrays.asList(
      Indexed.index(0, "Afrim"), 
      Indexed.index(2, "Besim"), 
      Indexed.index(4, "Durim"));
    List> actualResult 
      = StreamIndices.getEvenIndexedStrings(names);
    
    assertEquals(expectedResult, actualResult);
}

4. Использование StreamEx

Мы также можем итерировать с индексами, используя filterKeyValue () ВходСтрим класс из StreamEx библиотека (последняя версия можно найти здесь ). Во-первых, мы должны добавить его в нашу пом.xml:


    one.util
    streamex
    0.6.5

Давайте посмотрим простое применение этого метода, используя наш предыдущий пример:

public List getEvenIndexedStringsVersionTwo(List names) {
    return EntryStream.of(names)
      .filterKeyValue((index, name) -> index % 2 == 0)
      .values()
      .toList();
}

Мы будем использовать аналогичный тест, чтобы проверить это:

@Test
public void whenCalled_thenReturnListOfEvenIndexedStringsVersionTwo() {
    String[] names 
      = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
    List expectedResult 
      = Arrays.asList("Afrim", "Besim", "Durim");
    List actualResult 
      = StreamIndices.getEvenIndexedStrings(names);
   
   assertEquals(expectedResult, actualResult);
}

5. Итерация с использованием потока Вавра

Другим вероятным способом итерации является использование zipWithIndex () метод Вавр (ранее известный как Явасланг ) в Поток реализация:

public List getOddIndexedStringsVersionTwo(String[] names) {
    return Stream
      .of(names)
      .zipWithIndex()
      .filter(tuple -> tuple._2 % 2 == 1)
      .map(tuple -> tuple._1)
      .toJavaList();
}

Мы можем протестировать этот пример следующим методом:

@Test
public void whenCalled_thenReturnListOfOddStringsVersionTwo() {
    String[] names 
      = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"};
    List expectedResult 
      = Arrays.asList("Bashkim", "Lulzim", "Shpetim");
    List actualResult 
      = StreamIndices.getOddIndexedStringsVersionTwo(names);

    assertEquals(expectedResult, actualResult);
}

Если вы хотите узнать больше о Vavr, проверьте эту статью.

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

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

Есть много функций, которые включены в Java 8 Streams, некоторые из которых уже охвачены на Baeldung .

Код для всех примеров, объясненных здесь, и многое другое можно найти более на GitHub .