Замыкания в Groovy - реализация на эквивалентном Java

У меня есть следующий Groovy скрипт:

def n = ["1","2","3"]
println n.collect { v -> v.toInteger()*2 }

И я хотел бы перевести его в эквивалентный Java-код (абстрагируясь от значения "собирать" - не имеет значения, что он делает сейчас).

Я написал следующее:

class X {
   X() {
          object[] n = new object[]{"1","2","3"};

          object anonymousBlock(object v) { return v.toInteger()*2; }

          System.out.println(n.collect(???));
   }
}

Что я должен передать в качестве аргумента для сбора с использованием представленного выше представления?

1 ответ

Решение

С Java 8 вы можете сделать:

List<String> strings = Arrays.asList( "1","2","3" ) ;
List<Integer> numbers = strings.stream()
                               .map( Integer::parseInt )
                               .map( (i) -> i * 2 )
                               .collect( Collectors.toList() ) ;

В Java 7 один из подходов выглядит примерно так:

Сначала определите интерфейс для преобразования из одного типа в другой:

static interface Mapper<T,U> {
    U apply( T value ) ;
}

Затем мы можем определить класс, который делегирует итератору и применяет Mapper.apply метод для каждого элемента, как он возвращается:

static class Collector<T,U> implements Iterator<U> {
    Iterator<T> delegate ;
    Mapper<T,U> mapper ;

    public Collector( Iterable<T> elements, Mapper<T,U> c ) {
        delegate = elements.iterator() ;
        this.mapper = c ;
    }

    @Override
    public void remove() { delegate.remove() ; }
    @Override
    public boolean hasNext() { return delegate.hasNext() ; }
    @Override
    public U next() { return mapper.apply( delegate.next() ) ; }
}

Затем мы можем назвать это, используя что-то вроде:

List<String> strings = Arrays.asList( "1","2","3" ) ;

// Create our mapping Iterator
Iterator<Integer> iter = new Collector<>( strings, new Mapper<String,Integer>() {
    @Override
    public Integer apply( String v ) {
        return Integer.parseInt( v ) * 2 ;
    }
} ) ;

// Collect back from iterator into a List
List<Integer> numbers = new ArrayList<>() ;
while( iter.hasNext() ) {
    numbers.add( iter.next() ) ;
}

Java 8 и Groovy FTW;-)

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