Java 8新特性 函数式接口&方法引用&lambda表达式

 在阅读别人写的代码的时候,我注意到了一种写法。如下:

public interface Iface {
    void doit(Integer i,String s);
}
public class Mapmap {
    public static Map map=new HashMap();
}
public class Functiondemo {
    {
        Mapmap.map.put(1,this::m1);
        Mapmap.map.put(2,this::m2);
    }
    public void m1(Integer i,String s){
        System.out.println("m1");
    }
​
    public void m2(Integer i,String s){
        System.out.println("m2");
    }
}
public class Main {
    public static void main(String[] args) {
        Functiondemo functiondemo=new Functiondemo();
        Iface iface = Mapmap.map.get(2);
        iface.doit(2, "ss");
    }
}

运行结果:

Java 8新特性 函数式接口&方法引用&lambda表达式_第1张图片

 

调试后发现iface.doit(2, "ss");执行的是Functiondemo中的m2()。

 

经过查找之后发现这其实Java 8 中提提供的新特性的一种写法。在上面使用了函数式接口和方法引用一起实现的,这样就可以在一个类中实现多个同一方法。

下面具体了解一下Java 8提供的这两个特性:

1.函数式接口:

函数式接口(functional interface 也叫功能性接口,其实是同一个东西)。简单来说,函数式接口是只包含一个方法的接口。比如Java标准库中的java.lang.Runnable和 java.util.Comparator都是典型的函数式接口。 java 8提供 @FunctionalInterface作为注解,这个注解是非必须的,只要接口符合函数式接口的标准(即只包含一个方法的接口),虚拟机会自动判断,(如上面例子就没有添加注解) 但最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。

除上面那种使用方法之外,常常也使用lambda表达式来实现接口。Java中的lambda无法单独出现,它需要一个函数式接口来盛放,lambda表达式方法体其实就是函数接口的实现.

2.方法引用:

其实是lambda表达式的一种简化写法。所引用的方法其实是lambda表达式的方法体实现,语法也很简单,左边是容器(可以是类名,实例名),中间是"::",右边是相应的方法名。如果你觉得lambda的方法体会很长,影响代码可读性,方法引用就是个解决办法。

一般方法的引用格式:

  1. 如果是静态方法,则是ClassName::methodName。如 Object ::equals

  2. 如果是实例方法,则是Instance::methodName。如Object obj=new Object();obj::equals;

  3. 构造函数.则是ClassName::new

如上面所示:

Mapmap.map.put(1,this::m1);

就使用了方法引用。

3.lambda表达式:

ArrayList integers = new ArrayList<>();
        for(int i=0;i<10;i++){
            integers.add(i);
        }
integers.forEach(i-> System.out.println(i));
public static Future schedule(long delay, Runnable runnable) {
   return ScheduledThreadPool.schedule(runnable,delay, TimeUnit.MILLISECONDS);
}
//lambda表达式的使用
TimedTaskManager.schedule(
                    10000, () -> {
                        casualty.setState(1);
                        initPlayer(casualty);
                        notificationManager.notifyPlayer(casualty,casualty.getName()+"  你已经复活 \n");
                    }
            );

包含三部分:

1、一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数(从上面可以看到也可以没有这个括号)

2、一个箭头符号:->

3、方法体,可以是表达式(这个方法只需要执行一行代码,如第一个示例)和代码块(执行多行代码,如第二个示例)。

可以看到lambda表达式就是去执行一个方法,在方法中可以自己书写逻辑或者调用其他已存在的方法。

你可能感兴趣的:(JAVA)