6

所以我有我朋友给我看的这段代码,我必须承认我不明白发生了什么。我了解有关 Lamba 表达式的概念,并且在 haskell 中编写了很多,但到目前为止还没有在 Java 中编写。

令我困惑的是编译器如何知道我认为是 lambda 的函数应该是 Iterable 接口中所需的“iterator()”。

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

我有我的这个版本,但是我有一个阴影问题,我为实现 Iterable for values 所做的 iterator() 在其内部被调用,导致堆栈溢出。我想要的是使用在 values() 范围内定义但不知道如何指向它的 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;
        }
    }
}

注意:这个 iterator() 在 variables() 的范围内

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

1 回答 1

6

Lambda 表达式用于实现函数式接口,其中只有一种方法需要实现。因此,由于您的values()方法返回Iterable<V>,因此 lambda 表达式必须实现该接口的单一方法,即iterator().

至于示例中的 lambda 表达式的语法:

空括号()表示 lambda 表达式实现的方法没有参数,对于该iterator()方法来说确实如此。

在 之后,你有 lambda 表达式的主体,在这个例子中它返回一个实现接口->的匿名类的实例。Iterator<V>

哦,您的第二个代码片段会导致堆栈溢出,因为您的iterator()方法创建 的实例ValuesIterator,并且作为实例初始化的一部分,您调用该iterator()方法,导致无限递归。

于 2015-01-10T19:53:55.237 回答