Как получить индексный индекс объекта в цикле foreach Java8

Java

В Java 8 мы часто используем лямбда-выражения для циклов foreach, но часто мы хотим получить индекс объекта при обходе List, но Java 8, 9, 10 и 11 не имеют соответствующей поддержки, и та же проблема также существует в расширенном цикле for, много раз мне приходится плакатьfor (int i = 0; i < list.size(); i++)способ написания кода

наши ожидания

list.foreach((item,index)->{})  //编译不通过

Общий метод получения списка

for(int i=0;i<list.size();i++>)

for (int i = 0; i < list.size(); i++) {   
}

indexOf(Obj)

for (Object o : list) {
    list.indexOf(o); //如果是Set还没有这个方法
}

а также…

int i = 0;
for (String s : list) {
    i++;
}

Очевидно, что вышеуказанный метод не то, что нам нужно.

Потребитель и Бипотребитель

Давайте рассмотрим простой пример

Consumer<String> consumer = t -> System.out.println(t);
consumer.accept("single");
BiConsumer<String, String> biConsumer = (k, v) -> System.out.println(k+":"+v);
biConsumer.accept("multipart","double params");

Выходной результат:

single
multipart:double params

Здесь нетрудно обнаружить, что стрелочная функция, которую мы обычно пишем, на самом деле является объектом Consumer или BiConsumer.

Пользовательский потребитель

исходный код для каждого

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

Анализ исходного кода показывает, что наш метод list foreach передает в объект Consumer, который поддерживает один параметр, а нам нужны два параметра, item и index, что явно не устраивает.На данный момент мы можем настроить Consumer, а параметры BiConsumer, это может удовлетворить наши потребности, код выглядит следующим образом:

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public class LambadaTools {
    /**
     * 利用BiConsumer实现foreach循环支持index
     *
     * @param biConsumer
     * @param <T>
     * @return
     */
    public static <T> Consumer<T> forEachWithIndex(BiConsumer<T, Integer> biConsumer) {
        /*这里说明一下,我们每次传入forEach都是一个重新实例化的Consumer对象,在lambada表达式中我们无法对int进行++操作,
        我们模拟AtomicInteger对象,写个getAndIncrement方法,不能直接使用AtomicInteger哦*/
        class IncrementInt{
            int i = 0;
            public int getAndIncrement(){
                return i++;
            }
        }
        IncrementInt incrementInt = new IncrementInt();
        return t -> biConsumer.accept(t, incrementInt.getAndIncrement());
    }
}

Пример вызова:

List<String> list = new ArrayList();
list.add("111");
list.add("222");
list.add("333");
list.forEach(LambadaTools.forEachWithIndex((item, index) -> {
    System.out.println(index +":"+ item);
}));

Результат выглядит следующим образом:

0:111
1:222
2:333

PS: Этот набор также можно использовать, но этот индекс не является нижним индексом в использовании набора.