So I have this piece of code my friend showed me and I must admit I do not understand what is going on. I understand the concept around lamba expressions and have written quite a few of them in haskell but none in Java so far.
What confuses me is how does the compiler know that the function which I supposed is lambdaed is supposed to be the "iterator()" one required in the Iterable interface.
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();
}
};
};
}
I have my version of this but I have a problem with shadowing where the iterator() I make to implement Iterable for values is called inside itself causing stack overflow. What I want is to use the iterator() which is defined in the scope of the values() but don't know how to point to it.
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;
}
}
}
note: this iterator() is in the scope of variables()
public Iterator<SimpleHashtable.TableEntry<K, V>> iterator() {
return new TableEntryIterator();
}
Lambda expressions are used to implement functional interfaces, in which there is only one method that requires implementation. Therefore, since your values()
method returns Iterable<V>
, the lambda expression must implement the single method of that interface, which is iterator()
.
As for the syntax of the lambda expression in your example :
The empty brackets ()
mean that the method implemented by the lambda expression has no arguments, which is indeed true for the iterator()
method.
After the ->
, you have the body of the lambda expression, which in this example returns an instance of an anonymous class that implements the Iterator<V>
interface.
Oh, and your second code snippet causes stack overflow because your iterator()
method creates an instance of ValuesIterator
, and as part of the initialization of the instance, you call that iterator()
method, causing an infinite recursion.