Java Lambda表达式

前言

随着函数式编程的流程,Java8中也引入了函数式编程风格(Lambda表达式)。Lambda表达式允许我们将行为传递到函数中,其可以替换匿名内部类实现的繁琐的代码。下面就是一个最经典的例子,用普通的匿名内部类一共用了6行代码,使用Lambda表达式只需要1行代码即可。也就是说,Lambda表达式在经常使用内部类情况下,可以大大的减少代码量,还有就是Lambda表达式经常和Stream API一起使用。

// 匿名内部类
Runnable runnable1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("do something");
    }
};
// Lambda表达式
Runnable runnable2 = () -> System.out.println("do something");

Lambda表达式使用

Lambda表达式格式

(Type1 param1, Type2 param2, ..., TypeN typeN) -> {
    statment1;
    statment2;
    // ......
    return statmentM;
}

操作符'->':Lambda操作符,该箭头将Lambda表达式拆分为左右两部分

左侧:参数列表,只有一个参数时可以不写()

右侧:Lambda表达式体,就抽象方法实现区域。只有一行代码时可以不写{},参数类型也可以不用写(Java会通过上下文进行判断)

上面是标准的Lambda表达式,一般情况下Lambda表达式可以分为以下几种类型:

无参数无返回值

() -> {
    statment1;
    statment2;
    ...
    statmentN;
}

有参数无返回值

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
    statment1;
    statment2;
    ...
    statmentN;
}

有参数有返回值

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
    statment1;
    statment2;
    ...
    statmentN;
    return value;
}

下面是一个实现List排序功能(根据字符串长度)的例子,可以看到这个例子是有参有返回值的,但是没有写return值(在单见场景下可以省略不写)

List<String> list = new ArrayList<>();
list.add("my");
list.add("name");
list.add("is");
list.add("super");
list.add("man");
// 非lambda实现排序
Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }
});
list.stream().forEach((x)->System.out.println(x));

// lambda实现排序
Collections.sort(list, (o1, o2) -> o2.length() - o1.length());
list.stream().forEach((x)->System.out.println(x));

函数式接口

定义与Lambda关系

函数式接口就是一个有且仅有一个抽象方法,但是有多个非抽象方法的接口。Lambda表达式需要函数式接口的支持,下面是自定义的函数式接口:

@FunctionalInterface
public interface TestService {
    void test();
}

// 使用代码
TestService testService = ()->System.out.println("test");
testService.test();

@FunctionalInterface注解用于标识该接口是函数式接口,如果不满足函数式接口规则,则编译会报错,当然函数式接口并不一定需要@FunctionalInterface注解。

Java中四种函数式接口

Java中常用的四个核心函数式接口包括:1、Consumer<T> 消费型接口;2、Supplier<T> 供给型接口;3、Function<R, T> 函数型接口;4、Predicate<T> 断言型接口

消费型接口(Consumer<T>)

@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); };
    }
}

主要方法:
accept(T t):接受一个指定类型的参数,但无返回值

andThen(Consumer<? super T> after):从左向右执行

List<String> list2 = Arrays.asList("a","bb","ccc","dddd","eeeee");
Consumer<String> consumer = (x) -> System.out.println("input:" + x);
list2.stream().forEach(consumer);

供给型接口(Supplier<T>)

@FunctionalInterface
public interface Supplier<T> {

    T get();

}

主要方法:

T get():不接受任何参数,但返回执行类型的值

List<Integer> list1 = new ArrayList<>();
Supplier<Integer> supplier = () -> (int)(Math.random() * 100);
for (Integer i = 0; i < 10; i++) {
    list1.add(supplier.get());
}
list1.stream().forEach((x) -> System.out.println(x));

函数型接口(Function<R, T>)

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

主要方法:

R apply(T t):接受一个指定类型的参数,返回一个执行的结果类型

andThen和compose方法:执行顺序不一样,andThen是从左向右执行;compose是从右向左执行;

Function<String, String> function1 = (x) -> x.toUpperCase();
List<String> list4 = list2.stream().map(function1).collect(Collectors.toList());
for (String elem : list4) {
    System.out.println("String Upper:" + elem);
}

Function<Integer, Integer> function2 = (x) -> x * 3;
Function<Integer, Integer> function3 = (x) -> x + 8;

System.out.println("andThen:" + function2.andThen(function3).apply(1));
System.out.println("compose:" + function2.compose(function3).compose(function3).apply(1));

断言型接口(Predicate<T>)

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

主要方法:

boolean test(T t):传入指定值用于判断,返回true或者false

and、negate、or、isEqual方法代表与、非、或、相等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章