Лямбда-выражение в итерируемой реализации
Итак, у меня есть этот код, который мне показал мой друг, и я должен признать, что не понимаю, что происходит. Я понимаю концепцию ламба-выражений и написал немало из них на языке 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