Таким образом, пройдет почти год — но поскольку Java сейчас разрабатывается с открытым исходным кодом, мы можем взглянуть и попробовать использовать ее прямо сейчас. Итак, начнем!
Загрузите и установите Lambda с поддержкой Java 8
Во-первых, я ожидал, что мне придется самому скомпилировать Java 8, поскольку он еще не выпущен. Но я был приятно удивлен, увидев, что бинарная сборка доступна для всех платформ по адресу http://jdk8.java.net/lambda/ . Поэтому я только что скачал последнюю версию предварительной сборки для разработчиков и установил ее на свой компьютер.
Чтобы убедиться, что это работает, я создал класс LambdaIntro, содержащий «Hello, World!», Скомпилировал и выполнил его:
1
2
3
4
5
|
~ $ export JAVA_HOME=~ /Devtools/Java/jdk1 .8.0/ ~ $ cd spikes /lambda-water ~ $ $JAVA_HOME /bin/javac src /net/jthoenes/blog/spike/lambda/LambdaIntro .java ~ $ $JAVA_HOME /bin/java - cp src net.jthoenes.blog.spike.lambda.LambdaIntro Hello from Java 8! |
Примечание : я использую командную строку для компиляции и выполнения здесь, потому что IDE не поддерживают Java 8 на данный момент.
Не Лямбда Путь
В качестве примера давайте предположим, что я хочу просмотреть список объектов. Но для моей бизнес-логики мне нужно иметь значение и индекс элемента списка. Если я хочу сделать это с текущей Java, я должен обработать индекс вместе с реальной логикой:
1
2
3
4
|
List list = Arrays.asList( 'A' , 'B' , 'C' ); for ( int index = 0 ; index < list.size(); index++) { String value = list.get(index); String output = String.format( '%d -> %s' , index, value); System.out.println(output); } |
Это будет выводить
1
2
3
|
0 -> A 1 -> B 2 -> C |
Это не так уж плохо, но я сделал две вещи в одних и тех же нескольких строках кода: управление итерацией и предоставление некоторой (очень простой) бизнес-логики. Лямбда-выражения могут помочь мне разделить эти два. \
Подпись метода eachWithIndex
Поэтому я хочу иметь метод eachWithIndex, который можно вызвать так:
1
2
3
4
5
6
7
|
List list = Arrays.asList( 'A' , 'B' , 'C' ); eachWithIndex(list, (value, index) -> { String output = String.format( '%d -> %s' , index, value); System.out.println(output); } ); |
Метод получает два параметра. Первый — это список, а второй — лямбда-выражение или замыкание, которое указывает методу, что делать с каждым элементом списка. Как видно из строки 3, лямбда-выражение получает два аргумента: текущее значение и текущий индекс. Эти аргументы не имеют объявления типа. Информация о типе будет выведена компилятором Java 8. После аргументов есть -> и блок кода, который должен быть выполнен для каждого элемента списка.
Примечание : вам придется написать этот метод в обычном текстовом редакторе или игнорировать сообщения об ошибках в вашей IDE.
Реализуйте метод eachWithIndex
Чтобы использовать лямбду в Java 8, вам нужно объявить функциональный интерфейс. Функциональный интерфейс — это интерфейс, который имеет ровно один метод — метод, который будет реализован лямбда-выражением. В этом случае мне нужно объявить метод, который получает элемент и индекс и ничего не возвращает. Поэтому я определяю следующий интерфейс:
1
2
3
|
public static interface ItemWithIndexVisitor<E> { public void visit(E item, int index); } |
С помощью этого интерфейса я могу теперь реализовать метод eachWithIndex .
1
2
3
4
5
|
public static <E> void eachWithIndex(List<E> list, ItemWithIndexVisitor<E> visitor) { for ( int i = 0 ; i < list.size(); i++) { visitor.visit(list.get(i), i); } } |
В методе используется универсальный параметр <E> , поэтому будет выведено, что элемент, переданный методу посещения, того же типа, что и список.
Преимущество использования функциональных интерфейсов состоит в том, что их много в Java. Вспомните, например, интерфейс java.util.concurrent.Callable . Он может использоваться как лямбда-код без изменения кода, который использует Callable . Это делает большую часть лямбды JDK и фреймворков включенной по умолчанию.
Использование ссылки на метод
Одна маленькая удобная вещь из Project Lambda — это ссылки на методы. Это способ повторно использовать существующие методы и упаковать их в объект функционального интерфейса. Допустим, у меня есть следующий метод
1
2
3
4
|
public static <E> void printItem(E value, int index) { String output = String.format( '%d -> %s' , index, value); System.out.println(output); } |
и я хочу использовать этот метод в моем методе eachWithIndex , чем я могу использовать нотацию :: внутри моего вызова метода:
1
|
eachWithIndex(list, LambdaIntro::printItem); |
Выглядит красиво и лаконично, не так ли?
Резюме
Это запускает мой первый лямбда-пример. Я не мог избежать улыбки на лице, чтобы увидеть замыкания, запущенные в одной из моих Java-программ, после того, как они так долго тосковали по ним. В настоящее время лямбда-выражения доступны только для предварительного просмотра. Если вы хотите узнать больше, прочтите текущий предварительный обзор проекта или перейдите на страницу проекта Project Lambda .
Я загрузил полный пример кода в суть .
Ссылка: Java 8: тестирование лямбда-воды от нашего партнера JCG Йоханнеса Тунеса в блоге блога Йоханнеса Тунеса .