Як робити ітерацію над потоком з індексами

1. Огляд

Потоки Java 8 не є колекціями, і доступ до елементів неможливий за допомогою їхніх індексів, але все ж існує кілька хитрощів, щоб зробити це можливим.

У цій короткій статті ми розглянемо, як здійснити ітерацію потоку за допомогою IntStream, StreamUtils, EntryStream та Vavr 's Stream .

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 () метод StreamUtils з протонного пакету бібліотеки (остання версія може бути знайдена тут).

По-перше, вам потрібно додати його до вашого pom.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 () з EntryStream класу з StreamEx бібліотеки (остання версія може бути знайдена тут). Спочатку нам потрібно додати його до нашого pom.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. Ітерація Використання Vavre «s потік

Іншим можливим способом ітерації з використанням zipWithIndex () метод Vavr (раніше відомий як Javaslang ) 'и потік реалізації:

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); }

Якщо ви хочете прочитати більше про Вавр, перегляньте цю статтю.

6. Висновок

У цьому короткому навчальному посібнику ми побачили чотири підходи до того, як здійснювати ітерацію потоків за допомогою індексів. Потоки привернули багато уваги, і можливість їх перегляду за допомогою індексів може бути корисною.

Є багато функцій, які включені в Java 8 Streams, деякі з яких вже охоплені Baeldung.

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