Java8 - 函数式接口

什么是函数式接口?

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。也叫做SAM ,即Single Abstract Method interfaces。

函数接口用在什么地方?

函数式接口可以被隐式转换为lambda表达式。

也可以用在方法引用上。

 

JDK 1.8之前已有的函数式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 新增加的函数接口:

  • java.util.function

java.util.function 它包含了很多类,用来支持 Java的 函数式编程,该包中的函数式接口有:

序号接口 & 描述
1BiConsumer<T,U>

代表了一个接受两个输入参数的操作,并且不返回任何结果

2BiFunction<T,U,R>

代表了一个接受两个输入参数的方法,并且返回一个结果

3BinaryOperator<T>

代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果

4BiPredicate<T,U>

代表了一个两个参数的boolean值方法

5BooleanSupplier

代表了boolean值结果的提供方

6Consumer<T>

代表了接受一个输入参数并且无返回的操作

7DoubleBinaryOperator

代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。

8DoubleConsumer

代表一个接受double值参数的操作,并且不返回结果。

9DoubleFunction<R>

代表接受一个double值参数的方法,并且返回结果

10DoublePredicate

代表一个拥有double值参数的boolean值方法

11DoubleSupplier

代表一个double值结构的提供方

12DoubleToIntFunction

接受一个double类型输入,返回一个int类型结果。

13DoubleToLongFunction

接受一个double类型输入,返回一个long类型结果

14DoubleUnaryOperator

接受一个参数同为类型double,返回值类型也为double 。

15Function<T,R>

接受一个输入参数,返回一个结果。

16IntBinaryOperator

接受两个参数同为类型int,返回值类型也为int 。

17IntConsumer

接受一个int类型的输入参数,无返回值 。

18IntFunction<R>

接受一个int类型输入参数,返回一个结果 。

19IntPredicate

:接受一个int输入参数,返回一个布尔值的结果。

20IntSupplier

无参数,返回一个int类型结果。

21IntToDoubleFunction

接受一个int类型输入,返回一个double类型结果 。

22IntToLongFunction

接受一个int类型输入,返回一个long类型结果。

23IntUnaryOperator

接受一个参数同为类型int,返回值类型也为int 。

24LongBinaryOperator

接受两个参数同为类型long,返回值类型也为long。

25LongConsumer

接受一个long类型的输入参数,无返回值。

26LongFunction<R>

接受一个long类型输入参数,返回一个结果。

27LongPredicate

R接受一个long输入参数,返回一个布尔值类型结果。

28LongSupplier

无参数,返回一个结果long类型的值。

29LongToDoubleFunction

接受一个long类型输入,返回一个double类型结果。

30LongToIntFunction

接受一个long类型输入,返回一个int类型结果。

31LongUnaryOperator

接受一个参数同为类型long,返回值类型也为long。

32ObjDoubleConsumer<T>

接受一个object类型和一个double类型的输入参数,无返回值。

33ObjIntConsumer<T>

接受一个object类型和一个int类型的输入参数,无返回值。

34ObjLongConsumer<T>

接受一个object类型和一个long类型的输入参数,无返回值。

35Predicate<T>

接受一个输入参数,返回一个布尔值结果。

36Supplier<T>

无参数,返回一个结果。

37ToDoubleBiFunction<T,U>

接受两个输入参数,返回一个double类型结果

38ToDoubleFunction<T>

接受一个输入参数,返回一个double类型结果

39ToIntBiFunction<T,U>

接受两个输入参数,返回一个int类型结果。

40ToIntFunction<T>

接受一个输入参数,返回一个int类型结果。

41ToLongBiFunction<T,U>

接受两个输入参数,返回一个long类型结果。

42ToLongFunction<T>

接受一个输入参数,返回一个long类型结果。

43UnaryOperator<T>

接受一个参数为类型T,返回值类型也为T。

函数式接口举例

demo1 Function<T,R>  

java.util.function.Function<T, R>接口定义了一个叫作apply的方法,它接受一个 泛型T的对象,并返回一个泛型R的对象。如果你需要定义一个Lambda,将输入对象的信息映射到输出,就可以使用这个接口。

package com.common;

import java.util.Date;
import java.util.function.Function;

public class FunctionInterfaceTest {

    /**
     * 如果你想把接受一些输入参数并将对输入参数处理过后的结果返回的功能封装到一个方法内,Function接口是一个不错的选择。
     * 输入的参数类型和输出的结果类型可以一致或者不一致。
     *
     * @param valueToBeOperated
     * @param function
     */
    static void modifyTheValue(int valueToBeOperated, Function<Integer, Integer> function) {
        int newValue = function.apply(valueToBeOperated);
        /*
         * Do some operations using the new value.
         */
        System.out.println(newValue);
    }


    public static void main(String[] args) {

        Function<String, Student> function = (name) -> {
            return new Student(name);
        };
        function = Student::new;

        Student student = function.apply("sdsd");

        modifyTheValue(1, (val) -> val + 100);

        Function<Integer, Integer> incr100Function = (val) -> {
            return val + 100;
        };

        Function<Integer, Integer> incr200Function = (val) -> {
            return val + 200;
        };

        incr100Function.andThen(incr200Function);

        int res = incr100Function.andThen(incr200Function).apply(1);

        System.out.println(res);

    }
}

class Student {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    int age;
    Date birthday;
    Sex gender;
    String emailAddress;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Sex getGender() {
        return gender;
    }

    public void setGender(Sex gender) {
        this.gender = gender;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public Date getBirthday() {
        return birthday;
    }

    public static Integer compareByAge(Person a, Person b) {
        return a.age - b.age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Student{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append(", birthday=").append(birthday);
        sb.append(", gender=").append(gender);
        sb.append(", emailAddress='").append(emailAddress).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

demo2 Consumer<T> 

java.util.function.Consumer<T>定义了一个名叫accept的抽象方法,它接受泛型T 的对象,没有返回(void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用 这个接口。比如,你可以用它来创建一个forEach方法,接受一个Integers的列表,并对其中 每个元素执行操作。

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

不像其他函数式接口,Consumer接口期望执行带有副作用的操作(Consumer的操作可能会更改输入参数的内部状态)。使用方式如下,

package com.common;

import java.util.function.Consumer;

public class ConsumerInterfaceTest {

    static class Task {
        int status;
        String name;
    }

    static Task task;

    static {
        task = new Task();
        task.status = 1;
    }


    public static void handler(Consumer<Task> action) {
        action.accept(task);
    }


    public static void main(String[] args) {
        handler((task -> {
            task.status = 0;
        }));

        System.out.println(task.status);
    }
}

demo3 Supplier<T> 

public interface Supplier<T> {
    /**
     * Gets a result.
     * @return a result
     */
    T get();
}

不接受参数,返回一个结果

package com.common;

import java.util.function.Supplier;

public class SupplierInterfaceTest {

    static class Product {
        String type;
        double price;

        public Product(String type, double price) {
            this.type = type;
            this.price = price;
        }
    }

    private Supplier<Product> productSupplier = () -> {
        return new Product("test", 0.01);
    };


    public static void main(String[] args) {
        SupplierInterfaceTest supplierInterfaceTest = new SupplierInterfaceTest();
        Product product = supplierInterfaceTest.productSupplier.get();
    }
}

demo4 Predicate<T>

java.util.function.Predicate<T>接口定义了一个名叫test的抽象方法,它接受泛型 T对象,并返回一个boolean。在需要 表示一个涉及类型T的布尔表达式时,就可以使用这个接口。


package java.util.function;

import java.util.Objects;

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     */
    boolean test(T t);

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * AND of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code false}, then the {@code other}
     * predicate is not evaluated.
     *
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     * Returns a predicate that represents the logical negation of this
     * predicate.
     *
     */
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    /**
     * Returns a composed predicate that represents a short-circuiting logical
     * OR of this predicate and another.  When evaluating the composed
     * predicate, if this predicate is {@code true}, then the {@code other}
     * predicate is not evaluated.
     *
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    /**
     * Returns a predicate that tests if two arguments are equal according
     * to {@link Objects#equals(Object, Object)}.
     *
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

如下示例 ,

package com.common;

import java.util.function.Predicate;

public class PredicateInterfaceTest {

    static class TaskInfo {
        String name;
        int status;
    }


    private Predicate<TaskInfo> taskInfoPredicate = taskInfo -> {
        return taskInfo.status == 0;
    };

    private Predicate<TaskInfo> taskInfoNamePredicate = taskInfo -> {
        return taskInfo.name.compareTo("b") == 0;
    };


    public static void main(String[] args) {
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.status = 0;
        taskInfo.name = "abs";

        PredicateInterfaceTest predicateInterfaceTest = new PredicateInterfaceTest();
        boolean res = predicateInterfaceTest.taskInfoPredicate.test(taskInfo);
        System.out.println(res);
        res = predicateInterfaceTest.taskInfoPredicate.and(predicateInterfaceTest.taskInfoNamePredicate).test(taskInfo);
        System.out.println(res);

    }
}

=========END=========

转载于:https://my.oschina.net/xinxingegeya/blog/1941767

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值