эта статьяgithub/JavaMapОн был включен, есть карта расширенных технических знаний Java-программистов и моя серия статей, добро пожаловать в Star.
Выпущенная Oracle в 2014 году, Java8 является самой революционной версией со времен Java5.
Java8 вбирает в себя суть других языков и предоставляет ряд новых функций, таких как функциональное программирование, лямбда-выражения, потоки Stream и т. д. Изучение этих новых функций позволит вам достичь эффективного и элегантного кодирования.
1. Небольшой испытательный нож Lambda Express
Lambada表达式
Это можно понять как:可传递的匿名函数的一种简洁表达方式
. Лямбда-выражения не имеют имен и имеют списки параметров, тела функций, типы возвращаемых значений и т. д., как и обычные методы;
Давайте посмотрим на пример просто, новый поток печатает строку, используя лямбда-выражение очень лаконично:
new Thread(() -> System.out.println("hello java8 lambda")).start()
Класс Thread принимает экземпляр типа Runnable.Глядя на исходный код Jdk, обнаруживается, что интерфейс Runnable является函数式接口
, который можно заменить непосредственно лямбда-выражением.
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Синтаксис лямбда-выражения очень прост:
() -> System.out.println("hello java8 lambda")
- () В круглых скобках указан список параметров, если параметр только один, его также можно записать так:
a -> System.out.println(a)
- -> Стрелка - фиксированный способ письма;
-
System.out.println("hello java8 lambda")
Для тела функции, если имеется несколько операторов, заключите их в фигурные скобки, например:
(a, b) -> {int sum = a + b; return sum;}
Таким образом, модуль выражения Lambda можно закрепить как:
(parameter) -> {expression} 或者 (parameter) -> {statements; statements; }
Только один параметр может опускать круглые скобки
Если вы не используете лямбда-выражения и используете анонимные внутренние классы, способ написания не такой элегантный.
// before Java8
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello java8 without lambda");
}
}).start();
2. Расширенное использование Lambda
(1) Функциональный интерфейс
Функциональный интерфейс есть只定义了一个抽象方法的接口
. Обратите внимание, что методы по умолчанию (по умолчанию) разрешены в Java 8. Даже если существует много методов по умолчанию, пока есть только один абстрактный метод, интерфейс остается функциональным интерфейсом.
Функциональные интерфейсы обычно имеют аннотацию @FunctionalInterface в классе, например:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
(2) Что могут делать функциональные интерфейсы?
Обычно лямбда-выражения используются вместе с функциональными интерфейсами, лямбда-выражения начинаются с内联
Форма обеспечивает реализацию абстрактных методов функционального интерфейса, рассматривая все выражение как экземпляр функционального интерфейса.
Перед лямбда-выражениями мы обычно использовали匿名内部类
Подробное сравнение см. в примере кода в первом подразделе.
(3) Дескриптор функции
Сигнатура абстрактного метода в функциональном интерфейсе в основном является сигнатурой лямбда-выражения, мы можем назвать это соответствие как函数描述符
. Очень важно абстрагировать абстрактный метод функционального интерфейса в дескриптор функции, очень легко писать лямбда-выражения, зная дескриптор функции. Например:
Интерфейс Runnable имеет абстрактный метод void run(), который принимает пустые параметры и возвращает void, тогда дескриптор функции можно вывести следующим образом:() -> void
Лямбда-выражение может быть записано как () -> System.out.println("hello java8 lambda")
(4) Часто используемые функциональные интерфейсы
Функциональные интерфейсы обычно используются в java8, а также определены для базового типа java.IntPredicate
, LongPredicate
Подробности см. в исходном коде jdk.
функциональный интерфейс | дескриптор функции |
---|---|
Predicate | T->boolean |
Consumer | T->void |
Function<T,R> | T->R |
Supplier | () -> T |
UnaryOperator | T -> T |
BinaryOperator | (T,T)->T |
BiPredicate<L,R> | (L,R)->boolean |
BiConsumer<T,U> | (T,U)->void |
BiFunction<T,U,R> | (T,U)->R |
Что касаетсяPredicate
, Consumer
, Function
Конкретные функции этих функциональных интерфейсов будут подробно представлены в следующих статьях, здесь необходимо только общее впечатление.
(5) Рефакторинг лямбда-выражений в ссылки на методы
方法引用
Его можно рассматривать как сокращение для лямбда-выражений, которые могут вызывать метод атрибута как参数传递
. Вы также можете рассматривать ссылки на методы как синтаксический сахар для лямбда-выражений, делая лямбда-выражения более лаконичными для написания. Например, отсортированные по возрасту учащихся:
// before
students.sort((s1, s2) -> s1.getAge.compareTo(s2.getAge()))));
// after 使用方法引用
students.sort(Comparator.comparing(Student::getAge()))));
Существует три основных типа ссылок на методы:
- Ссылка на статический метод
valueOf — это статический метод класса String, а ссылка на метод записывается как String::valueOf, что соответствует лямбда-выражению:a -> String.valueOf(a)
- Ссылки методов на методы экземпляра любого типа
length — это метод экземпляра класса String, а ссылка на метод записывается как String::length, что соответствует лямбда-выражению:(str) -> str.length()
- ссылки на методы экземпляров существующих объектов
Третье легко спутать со вторым.Существующий объект относится к методу экземпляра внешнего объекта (не входного объекта), который вызывается в лямбда-выражении, например:
String str = "hello java8";
() -> str.length();
Соответствующая ссылка на метод записывается какstr::length
, заметьте, нетString::length
Суммировать
Наконец, мы резюмируем три типа ссылок на методы следующим образом:
лямбда-выражение | ссылка на метод | |
---|---|---|
(args) -> ClassName.staticMethod(args) | ClassName::staticMethod | ссылка на метод статического метода |
(arg0, params) -> arg0.instanceMethod(params) | ClassName::instanceMethod | Справочник по внутреннему методу экземпляра |
arg0 (params) -> arg0.instanceMethod(params) |
arg0.instanceMethod | ссылка на метод внешнего экземпляра |
-- END --
Ежедневные лайки: Привет, технари, сначала лайкайте, а потом смотрите, чтобы выработать привычку, ваши лайки — движущая сила на моем пути вперед, а следующий выпуск будет более захватывающим.
Введение: Блогер окончил Хуачжунский университет науки и технологий со степенью магистра, он программист со страстью к технологиям и страстью к жизни. За последние несколько лет он побродил по многим интернет-компаниям первой линии и имеет многолетний опыт разработки.
Публичный номер поиска в Wechat [Архитектор, который любит смеяться], у меня есть технологии и истории, которые ждут вас.
Статья постоянно обновляется вgithub/JavaMapВы можете увидеть мою заархивированную серию статей в , с опытом интервью и техническими галантерейными товарами, добро пожаловать в Star.