2015-01-10 4 views
3

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

Что меня смущает, так это то, как компилятор знает, что функция, которую я предполагаю, лямбдай, должна быть «итератором» («требуется» в интерфейсе 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(); 
      } 
     }; 
    }; 
} 

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

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

ответ

4

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

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

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

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

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

+0

Не могли бы вы пояснить синтаксис этого конкретного использования? – ditoslav

+1

@DominikDitoIvosevic конечно, отредактированный ответ – Eran

+0

Спасибо за этот короткий и полный ответ :) – ditoslav