Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> java

Лямбда-выражения Java

Лямбда-выражения Java

В этой статье мы узнаем о лямбда-выражении Java и использовании лямбда-выражения с функциональными интерфейсами, общим функциональным интерфейсом и потоковым API с помощью примеров.

Лямбда-выражение было впервые представлено в Java 8. Его основная цель — увеличить выразительную мощь языка.

Но прежде чем приступить к лямбда-выражениям, нам сначала нужно понять функциональные интерфейсы.

<час>

Что такое функциональный интерфейс?

Если интерфейс Java содержит один и только один абстрактный метод, то он называется функциональным интерфейсом. Это единственный метод, определяющий назначение интерфейса.

Например, Runnable интерфейс из пакета java.lang; является функциональным интерфейсом, поскольку он представляет собой только один метод, т.е. run() .

Пример 1. Определение функционального интерфейса в Java

import java.lang.FunctionalInterface;
@FunctionalInterface
public interface MyInterface{
    // the single abstract method
    double getValue();
}

В приведенном выше примере интерфейс MyInterface имеет только один абстрактный метод getValue(). Следовательно, это функциональный интерфейс.

Здесь мы использовали аннотацию @FunctionalInterface . Аннотация заставляет компилятор Java указать, что интерфейс является функциональным интерфейсом. Следовательно, не позволяет иметь более одного абстрактного метода. Однако это не является обязательным.

В Java 7 функциональные интерфейсы рассматривались как отдельные абстрактные методы или SAM. тип. SAM обычно реализовывались с помощью анонимных классов в Java 7.

Пример 2. Реализация SAM с анонимными классами в Java

public class FunctionInterfaceTest {
    public static void main(String[] args) {

        // anonymous class
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I just implemented the Runnable Functional Interface.");
            }
        }).start();
    }
}

Вывод :

I just implemented the Runnable Functional Interface.

Здесь мы можем передать анонимный класс методу. Это помогает писать программы с меньшим количеством кода на Java 7. Однако синтаксис по-прежнему был сложным, и требовалось много дополнительных строк кода.

Java 8 расширила возможности SAM, сделав еще один шаг вперед. Поскольку мы знаем, что функциональный интерфейс имеет только один метод, нет необходимости определять имя этого метода при его передаче в качестве аргумента. Лямбда-выражение позволяет нам сделать именно это.

<час>

Введение в лямбда-выражения

Лямбда-выражение — это, по сути, анонимный или безымянный метод. Лямбда-выражение не выполняется само по себе. Вместо этого он используется для реализации метода, определенного функциональным интерфейсом.

Как определить лямбда-выражение в Java?

Вот как мы можем определить лямбда-выражение в Java.

(parameter list) -> lambda body

Новый оператор (-> ) известен как оператор стрелки или лямбда-оператор. Синтаксис может быть не ясен в данный момент. Давайте рассмотрим несколько примеров,

Предположим, у нас есть такой метод:

double getPiValue() {
    return 3.1415;
}

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

() -> 3.1415

Здесь метод не имеет параметров. Следовательно, левая часть оператора содержит пустой параметр. Правая часть — это тело лямбда-выражения, определяющее действие лямбда-выражения. В этом случае возвращается значение 3,1415.

<час>

Типы лямбда-тела

В Java тело лямбды бывает двух типов.

<сильный>1. Тело с одним выражением

() -> System.out.println("Lambdas are great");

Этот тип лямбда-тела называется телом выражения.

<сильный>2. Тело, состоящее из блока кода.

() -> {
    double pi = 3.1415;
    return pi;
};

Этот тип лямбда-тела известен как блочное тело. Тело блока позволяет телу лямбды включать несколько операторов. Эти операторы заключены в фигурные скобки, после которых необходимо добавить точку с запятой.

Примечание :Для тела блока у вас может быть оператор возврата, если тело возвращает значение. Однако тело выражения не требует оператора return.

<час>

Пример 3. Лямбда-выражение

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

Как упоминалось ранее, лямбда-выражение не выполняется само по себе. Скорее, он формирует реализацию абстрактного метода, определенного функциональным интерфейсом.

Итак, сначала нам нужно определить функциональный интерфейс.

import java.lang.FunctionalInterface;

// this is functional interface
@FunctionalInterface
interface MyInterface{

    // abstract method
    double getPiValue();
}

public class Main {

    public static void main( String[] args ) {

    // declare a reference to MyInterface
    MyInterface ref;
    
    // lambda expression
    ref = () -> 3.1415;
    
    System.out.println("Value of Pi = " + ref.getPiValue());
    } 
}

Вывод :

Value of Pi = 3.1415

В приведенном выше примере

<час>

Лямбда-выражения с параметрами

До сих пор мы создавали лямбда-выражения без каких-либо параметров. Однако, подобно методам, лямбда-выражения также могут иметь параметры. Например,

(n) -> (n%2)==0

Здесь переменная n внутри круглых скобок — это параметр, передаваемый в лямбда-выражение. Тело лямбды принимает параметр и проверяет, является ли он четным или нечетным.

Пример 4. Использование лямбда-выражения с параметрами

@FunctionalInterface
interface MyInterface {

    // abstract method
    String reverse(String n);
}

public class Main {

    public static void main( String[] args ) {

        // declare a reference to MyInterface
        // assign a lambda expression to the reference
        MyInterface ref = (str) -> {

            String result = "";
            for (int i = str.length()-1; i >= 0 ; i--)
            result += str.charAt(i);
            return result;
        };

        // call the method of the interface
        System.out.println("Lambda reversed = " + ref.reverse("Lambda"));
    }

}

Вывод :

Lambda reversed = adbmaL
<час>

Универсальный функциональный интерфейс

До сих пор мы использовали функциональный интерфейс, который принимает только один тип значения. Например,

@FunctionalInterface
interface MyInterface {
    String reverseString(String n);
}

Приведенный выше функциональный интерфейс принимает только String и возвращает String . Однако мы можем сделать функциональный интерфейс универсальным, чтобы можно было использовать любой тип данных. Если вы не уверены в универсальных шаблонах, посетите Java Generics.

Пример 5. Общий функциональный интерфейс и лямбда-выражения

// GenericInterface.java
@FunctionalInterface
interface GenericInterface<T> {

    // generic method
    T func(T t);
}

// GenericLambda.java
public class Main {

    public static void main( String[] args ) {

        // declare a reference to GenericInterface
        // the GenericInterface operates on String data
        // assign a lambda expression to it
        GenericInterface<String> reverse = (str) -> {

            String result = "";
            for (int i = str.length()-1; i >= 0 ; i--)
            result += str.charAt(i);
            return result;
        };

        System.out.println("Lambda reversed = " + reverse.func("Lambda"));

        // declare another reference to GenericInterface
        // the GenericInterface operates on Integer data
        // assign a lambda expression to it
        GenericInterface<Integer> factorial = (n) -> {

            int result = 1;
            for (int i = 1; i <= n; i++)
            result = i * result;
            return result;
        };

        System.out.println("factorial of 5 = " + factorial.func(5));
    }
}

Вывод :

Lambda reversed = adbmaL
factorial of 5 = 120

В приведенном выше примере мы создали общий функциональный интерфейс с именем GenericInterface. . Он содержит универсальный метод с именем func(). .

Здесь, внутри класса Main,

<час>

Лямбда-выражение и Stream API

В JDK8 добавлен новый пакет java.util.stream, который позволяет разработчикам Java выполнять такие операции, как поиск, фильтрация, сопоставление, сокращение или управление коллекциями, такими как Lists. .

Например, у нас есть поток данных (в нашем случае List из String ), где каждая строка представляет собой комбинацию названия страны и места страны. Теперь мы можем обработать этот поток данных и получить только места из Непала.

Для этого мы можем выполнять массовые операции в потоке с помощью комбинации Stream API и лямбда-выражения.

Пример 6. Демонстрация использования лямбда-выражений с Stream API

import java.util.ArrayList;
import java.util.List;

public class StreamMain {

    // create an object of list using ArrayList
    static List<String> places = new ArrayList<>();

    // preparing our data
    public static List getPlaces(){

        // add places and country to the list
        places.add("Nepal, Kathmandu");
        places.add("Nepal, Pokhara");
        places.add("India, Delhi");
        places.add("USA, New York");
        places.add("Africa, Nigeria");

        return places;
    }

    public static void main( String[] args ) {

        List<String> myPlaces = getPlaces();
        System.out.println("Places from Nepal:");
        
        // Filter places from Nepal
        myPlaces.stream()
                .filter((p) -> p.startsWith("Nepal"))
                .map((p) -> p.toUpperCase())
                .sorted()
                .forEach((p) -> System.out.println(p));
    }

}

Вывод :

Places from Nepal:
NEPAL, KATHMANDU
NEPAL, POKHARA

В приведенном выше примере обратите внимание на оператор

myPlaces.stream()
        .filter((p) -> p.startsWith("Nepal"))
        .map((p) -> p.toUpperCase())
        .sorted()
        .forEach((p) -> System.out.println(p));

Здесь мы используем такие методы, как filter() , map() и forEach() потокового API. Эти методы могут принимать лямбда-выражение в качестве входных данных.

Мы также можем определить наши собственные выражения на основе синтаксиса, который мы изучили выше. Это позволяет нам значительно сократить количество строк кода, как мы видели в приведенном выше примере.


java

  1. С# интерфейс
  2. Операторы Java
  3. Java-выражения, операторы и блоки
  4. Java-интерфейс
  5. Java-проба с ресурсами
  6. Java-аннотации
  7. Интерфейс против абстрактного класса в Java:в чем разница?
  8. Java — регулярные выражения
  9. Java — Интерфейсы
  10. Java 9 — методы частного интерфейса