zoukankan      html  css  js  c++  java
  • Lambda表达式与函数式接口

    1 Lambda表达式

    Java8 新特性

    1.1 从匿名内部类到Lambda

    匿名内部类的作用:当一个内部类只需为其创建一次对象,且以后也不会再被用到,就可以使用匿名内部类简化代码编写。

    例子:创建线程。

    new Thread(new Runnable() {
        @Override
        public void run() {
    		System.out.println("CLASS");
        }
    }).start();
    

    Lambda表达式:大部分场景下可以取代匿名内部类的新特性。

    创建线程的代码可以简化为

    new Thread(() -> {
        System.out.println("LAMBDA");
    }).start();
    

    此外,Lambda表达式还可以结合forEach用于容器的遍历。只需一行即可完成遍历。

    list.forEach(x -> System.out.println(x));
    

    1.2 Lambda语法

    完整的格式

    (TYPE parameter, TYPE parameter) -> { code }
    

    做减法,可以分情况省略部分。

    "()" 当parameter只有一个时,可以省略,例如list.forEach(x -> System.out.println(x));

    "{}" 当code只有一行时,可以省略,例子同上。

    "TYPE" 参数类型总是可以省略,编译器会自动识别。

    1.3 使用Lambda表达式的限制

    Lambda表达式只能实现函数式接口。

    2 函数式接口

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

    2.1 @FunctionalInterface

    一个让编译器强制检查接口是否为函数式的注解。

    2.2 函数式接口的类型

    Java在1.8之前就有一些函数式接口:Runnable,Callable,Comparator,FileFilter等等。

    Java1.8又新增了一批函数式接口,放在java.util.function包下(图未截完整)

    2.3 从函数式接口到Lambda

    2.3.1 Consumer

    Consumer:位于java.util.function包下,接收一个泛型的参数T,然后调用accept,对这个参数进行操作(accept为抽象方法,具体做什么操作由实现决定),没有返回值。

    @FunctionalInterface
    public interface Consumer<T> {
       	void accept(T t);
        //非抽象方法略
    }
    

    上面提到的forEach就接收了一个Consumer泛型接口

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    

    回到forEach配合Lambda进行遍历

    list.forEach(x -> System.out.println(x));
    

    Lambda表达式实现了Consumer接口,accept方法被重写为打印接收的参数x,在forEach方法内部通过for循环完成遍历。

    2.3.2 Predicate

    Predicate:位于java.util.function包下,接收一个泛型参数T,测试其是否符合test方法中的规则(test方法为抽象方法,具体规则由实现决定),返回一个boolean值。

    @FunctionalInterface
    public interface Predicate<T> {
        boolean test(T t);
        //非抽象方法略
    }
    

    removeIf:Collection中方法,用于条件删除容器中的元素,接收一个Predicate泛型接口。

    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
    

    删除list中小于3的元素

    list.removeIf(x -> x < 3);
    
  • 相关阅读:
    VS2010快捷键
    mvc 简单的分页扩展
    Asp.net(C#)给图片加上水印效果
    HTML特殊字符编码大全
    获取URL上的参数值
    json数据的时间格式转换如:/Date(2342561534)/
    js中文编码到C#后台解码
    获取浏览器滚动条高度
    使用js画图
    silverlight实时从Javascript获取json数据
  • 原文地址:https://www.cnblogs.com/CofJus/p/14459622.html
Copyright © 2011-2022 走看看