Functional Interfaces

Intro

Functional Interface

  • Это интерфейс ровно с одним абстрактным методом.

  • Может иметь другие не абстрактные (default, static) методы.

  • Может быть отмечен аннотаций @FunctionalInterface (@since 1.8):

    • Если отмечен, то compiler делает проверку на наличие ТОЛЬКО одного абстрактного метода.

Functional Interface

  • Общие функциональные интерфейсы находятся в модуле java.base в пакете java.util.function.

  • Встречаются и в других модулях и пакетах.

  • Можно создавать собственные функциональные интерфейсы.

Example

@FunctionalInterface
public interface Operation {
    int calculate();
}

Example

@FunctionalInterface
public interface Operation {
    int calculate();

    int calculate(int a);
}
error: Unexpected @FunctionalInterface annotation
@FunctionalInterface
^
  Operation is not a functional interface
    multiple non-overriding abstract methods found in interface Operation

java.util.Comparator

Comparator<T>

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);

    ...
}

Example

public class Student {
    private int id;
    private String name;
    private int age;

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }
}

Example

import java.util.Comparator;

public class AgeComparator implements Comparator<Student> {
    public int compare(Student s1, Student s2) {
        if (s1.getAge() == s2.getAge()) {
            return 0;
        } else if (s1.getAge() > s2.getAge()) {
            return 1;
        } else {
            return -1;
        }
    }
}

Example

import java.util.Comparator;

public class NameComparator implements Comparator<Student> {
    public int compare(Student o1, Student o2) {
        return s1.getName().compareTo(s2.getName());
    }
}

Example

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

public class ComparatorExample {
    public static void main(String[] args) {
        ArrayList students = new ArrayList();
        students.add(new Student(101, "Vijay", 23));
        students.add(new Student(106, "Ajay", 27));
        students.add(new Student(105, "Jai", 21));

        System.out.println("Sorting by Name...");

        Collections.sort(students, new NameComparator());
        Iterator itr = students.iterator();
        while (itr.hasNext()) {
            Student student = (Student) itr.next();
            System.out.println(student.getId() + " " + student.getName() + " " + student.getAge());
        }

        System.out.println("sorting by age...");

        Collections.sort(students, new AgeComparator());
        Iterator itr2 = students.iterator();
        while (itr2.hasNext()) {
            Student student = (Student) itr2.next();
            System.out.println(student.getId() + " " + student.getName() + " " + student.getAge());
        }
    }
}

java.lang.Comparable

Comparable<T>

  • Принимает объект одного типа и выполняет его сравнение с текущим объектом (this).

public interface Comparable<T> {
    public int compareTo(T o);
}

Example

class Student implements Comparable<Student> {
    private int id;
    private String name;
    private int age;

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int compareTo(Student st) {
        if (this.age == st.age) {
            return 0;
        } else if (this.age > st.age) {
            return 1;
        } else {
            return -1;
        }
    }
}

Example

import java.util.ArrayList;
import java.util.Collections;

public class CompareExample {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>();
        students.add(new Student(101, "Vijay", 23));
        students.add(new Student(106, "Ajay", 27));
        students.add(new Student(105, "Jai", 21));

        Collections.sort(students);
        for (Student student : students) {
            System.out.println(student.rollno + " " + student.name + " " + student.age);
        }
    }
}

java.util.function.Predicate

Predicate<T>

  • Принимает объект одного типа и выполняет проверку некоторого условия.

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);

    ...
}

Example

import java.util.function.Predicate;

public class Program {
    public static void main(String[] args) {
        Predicate<Integer> isPositive = x -> x > 0;

        System.out.println(isPositive.test(5));
        System.out.println(isPositive.test(-7));
    }
}

java.util.function.Consumer

Consumer<T>

  • Принимает объект одного типа и выполняет с ним бизнес-логику.

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);

    ...
}

Example

import java.util.function.Consumer;

public class Program {
    public static void main(String[] args) {
        Consumer<Integer> printer = x -> System.out.printf("%d долларов \n", x);
        printer.accept(600);
    }
}

java.util.function.Supplier

Supplier<T>

  • Порождает объекты данного типа.

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Example

public class User {
    private String name;

    public String getName() {
        return name;
    }

    public User(String n) {
        this.name = n;
    }
}

Example

import java.util.Scanner;
import java.util.function.Supplier;

public class Program {
    public static void main(String[] args) {
        Supplier<User> userFactory = () -> {
            Scanner in = new Scanner(System.in);
            System.out.println("Введите имя: ");
            String name = in.nextLine();
            return new User(name);
        };
        User user1 = userFactory.get();
        User user2 = userFactory.get();
        System.out.println("Имя user1: " + user1.getName());
        System.out.println("Имя user2: " + user2.getName());
    }
}

java.util.function.Function

Function<T, R>

  • Принимает объект одного типа, преобразует его в объект другого типа (или этого же типа) и возвращает его.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);

    ...
}

Example

import java.util.function.Function;

public class Program {
    public static void main(String[] args) {
        Function<Integer, String> convert = x -> String.valueOf(x) + " долларов";
        System.out.println(convert.apply(5)); // 5 долларов
    }
}

java.util.function.UnaryOperator

UnaryOperator<T>

@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
    ...
}

Example

import java.util.function.UnaryOperator;

public class Program {
    public static void main(String[] args) {
        UnaryOperator<Integer> square = x -> x * x;
        System.out.println(square.apply(5));
    }
}

java.util.function.BiFunction

BiFunction<T, U, R>

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);

    ...
}

java.util.function.BiConsumer

BiConsumer<T, U>

@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u);

    ...
}

java.util.function.BiPredicate

BiPredicate<T, U>

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);

    ...
}

java.util.function.BinaryOperator

BinaryOperator<T>

@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
    ...
}

Example

import java.util.function.BinaryOperator;

public class Program {
    public static void main(String[] args) {
        BinaryOperator<Integer> multiply = (x, y) -> x * y;

        System.out.println(multiply.apply(3, 5));
        System.out.println(multiply.apply(10, -2));
    }
}

java.lang.Runnable

Runnable

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

java.util.concurrent.Callable

Callable<V>

@FunctionalInterface
public interface Callable<V> {
    V call() throws Exception;
}

Other @FunctionalInterface

Other @FunctionalInterface

  • DoubleBinaryOperator

  • DoubleConsumer

  • DoubleFunction

  • DoublePredicate

  • DoubleSupplier

  • DoubleToIntFunction

  • DoubleToLongFunction

  • DoubleUnaryOperator

Other @FunctionalInterface

  • IntBinaryOperator

  • IntConsumer

  • IntFunction

  • IntPredicate

  • IntSupplier

  • IntToDoubleFunction

  • IntToLongFunction

  • IntUnaryOperator

Other @FunctionalInterface

  • LongBinaryOperator

  • LongConsumer

  • LongFunction

  • LongPredicate

  • LongSupplier

  • LongToDoubleFunction

  • LongToIntFunction

  • LongUnaryOperator

Other @FunctionalInterface

  • BooleanSupplier

  • ObjDoubleConsumer

  • ObjIntConsumer

  • ObjLongConsumer

Other @FunctionalInterface

  • ToDoubleBiFunction

  • ToDoubleFunction

  • ToIntBiFunction

  • ToIntFunction

  • ToLongBiFunction

  • ToLongFunction