Лямбда-выражение в итерируемой реализации

Итак, у меня есть этот код, который мне показал мой друг, и я должен признать, что не понимаю, что происходит. Я понимаю концепцию ламба-выражений и написал немало из них на языке haskell, но пока ни одного на Java.

Что меня смущает, так это то, как компилятор знает, что функция, которую я предположил, является лямбда-выражением, должна быть "iterator()", требуемой в интерфейсе Iterable.

public Iterable<V> values() {
    return () -> {
        return new Iterator<V>() {
            private Iterator<TableEntry<K, V>> iter = iterator();

            @Override
            public boolean hasNext() {
                return iter.hasNext();
            }

            @Override
            public V next() {
                return iter.next().getValue();
            }
        };
    };
}

У меня есть моя версия этого, но у меня есть проблема с теневым копированием, когда iterator (), который я создаю для реализации Iterable для значений, вызывается внутри себя, вызывая переполнение стека. Я хочу использовать iterator (), который определен в области значений (), но не знаю, как на него указать.

public Iterable<V> values() {
    return new ValuesIterable<V>();
}

public class ValuesIterable<V> implements Iterable<V>{
    public Iterator<V> iterator() {
        return new ValuesIterator();
    }

    public class ValuesIterator implements Iterator<V>
    {
        Iterator<SimpleHashtable.TableEntry<K, V>> iter = (Iterator<TableEntry<K, V>>) iterator();

        public boolean hasNext()
        {
            return iter.hasNext();
        }

        public V next()
        {
            return iter.next().getValue();
        }

        public void remove()
        {
            return;
        }
    }
}

примечание: этот итератор () находится в области переменных ()

public Iterator<SimpleHashtable.TableEntry<K, V>> iterator() {
    return new TableEntryIterator();
}

1 ответ

Решение

Лямбда-выражения используются для реализации функциональных интерфейсов, в которых есть только один метод, который требует реализации. Поэтому, так как ваш values() метод возвращает Iterable<V>лямбда-выражение должно реализовывать единственный метод этого интерфейса, который iterator(),

Что касается синтаксиса лямбда-выражения в вашем примере:

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

После ->, у вас есть тело лямбда-выражения, которое в этом примере возвращает экземпляр анонимного класса, который реализует Iterator<V> интерфейс.

Да, и ваш второй фрагмент кода вызывает переполнение стека, потому что ваш iterator() метод создает экземпляр ValuesIteratorи как часть инициализации экземпляра, вы называете это iterator() метод, вызывающий бесконечную рекурсию.

Java лямбда-выражение для итерации по списку

List pointList = new ArrayList();
pointList.add("1");
pointList.add("2");

pointList.forEach(p -> {
        System.out.println(p)
    }
);

Output:

1
2
Другие вопросы по тегам