欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量

程序员文章站 2022-05-22 20:35:28
...

一提到java是一种什么语言?

大多数人肯定异口同声的说是一门面向对象的语言,这种观点从我们开始学java就已经根深蒂固了,但是学到java8新特性函数式编程的时候,我才知道java并不是纯面向对象的语言。

lambda表达式的详细教程

lambda代码练习:

package Lambda;

public interface ImyWork {
    void dowork();

}
package Lambda;

import org.junit.Before;
import org.junit.Test;

public class LambdaTest {
    public LambdaTest() {
        System.out.println("构造方法");
    }
    public void wrapWork(ImyWork work){
        System.out.println("doworking");
        work.dowork();
    }
    @Test
    public void test(){
        //原始代码
/*      this.wrapWork(new ImyWork() {

            @Override
            public void dowork() {
                System.out.println("dowork");
            }
        });
        System.out.println("testing");*/
        //简化
        this.wrapWork(()->System.out.println("dowork"));
        System.out.println("testing");
    }
}

函数式编程

并行并发/基于事件的开发

举个Jquery中例子:

$(functionn(){
    $('.click').click(function(){
        myClickLogic();
})

那么我们在java中也可以写成如上的代码样式?

        List<Integer> a = new ArrayList<>();
        a.add(1);
        a.add(3);
        a.add(2);
        a.add(4);
        //传统写法
        a.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o2, o1);
            }
        });
        //lambda表达式
        a.sort((o1,o2)->Integer.compare(o2, o1));
        System.out.println(a);

函数式接口

1.我们把能够写lambda表达式的地方?一个接口,且接口里面只有一个抽象方法
2.在java中,把只有一个抽象方法的接口称为函数式接口,如果一个接口是函数式接口,我们可以在接口上添加@FunctionalInterface标签标明这是一个函数式接口(接上注解@..会提供报错警告也就是如果书写的不满足函数式接口会报错,否则不会报错)
3.无论是否标示@FunctionalInterface,只要满足函数式接口的接口,java都会直接识别为函数式接口
4.简化函数式接口的使用是java中提供lambda表达式唯一的作用
5.可以用接口来引用表达式,如上述Test中的代码可以写成ImyWork work=()->System.out.println("dowork");
this.wrapWork(work);
编译后编译器会帮我们向接口ImyWork反推出之前原本的代码
6.函数式接口里面可以写Object对象中的方法
7.lambda表达式中的异常处理:lambda表达式中产生的异常要么直接在代码块中处理
//第一种方法抛出异常
private void test1() {
ImyWork work=()->System.out.println("dowork");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.wrapWork(work);
}

要么在接口方法声明时抛出 如下所示

@FunctionalInterface
public interface ImyWork {
    void dowork() throws Exception;

}

方法引用

概念

1.类::方法(如上代码就是属于这种)

public class FunYinYong {
    public static void main(String[] args) {
        List<Integer> a = new ArrayList<>();
        a=Arrays.asList(1,2,4,3);
        /*常用的lambda表达式*/
        a.sort((x,y)->Integer.compare(x, y));
        System.out.println(a);
        /*lambda表达式中的方法引用*/
        a.sort(Integer::compare);
    }
}
  1. 对象::方法
public class FunYinYong {
    public FunYinYong(){

    }
    private int compare(int x,int y) {
        return Integer.compare(x, y);
    }
    public static void main(String[] args) {
        List<Integer> a = new ArrayList<>();
        a=Arrays.asList(1,2,4,3);
        /*lambda表达式*/
        a.sort((x,y)->Integer.compare(x, y));
        System.out.println(a);
        /*方法引用 类::方法*/
        a=Arrays.asList(1,2,4,3);
        a.sort(Integer::compare);
        System.out.println(a);
        /*方法引用 对象::方法*/
        a=Arrays.asList(1,2,4,3);
        FunYinYong it = new FunYinYong();
        a.sort(it::compare);
        System.out.println(a);
        /*对象::方法 foreach方法使用*/
        a.forEach(num->System.out.print(num));
        System.out.println();
        /*对象::方法 foreach方法使用最简式 */
        a.forEach(System.out::print);
    }
    @Test
    void Test(){
        /*this也可以使用但不能再main方法中使用因为main方法为静态方法在独立空间内获取不到当前类的对象*/
        List<Integer> a = new ArrayList<>();
        a=Arrays.asList(1,2,4,3);
        a.sort(this::compare);
        System.out.println(a);

    }
}

3.类构造方法引用 类::new ,构造器引用对应的函数式接口里面的方法个事一定是返回一个对象/方法没有参数,懒得敲代码了截图吧!
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量

接口默认方法

接口的默认方法和静态方法

java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量

内部类访问外部变量

确实如此,我们不能在局部内部类中修改局部变量,甚至在局部内部类外修改被局部内部类使用但没有声明为final的局部变量,这一切和java8之前一样,java8中唯一改变的就是我们不用显示的在一个局部变量前加上final关键字,如果我们反编译生成的类文件,可以看到,编译器已经相应的位置上加上了final关键字。不过,即使只有这一点改变,也算是改进,至少我们不必无缘无故的在某个方法参数或者局部变量前加上final

还有新特性等以后参加工作并且深入学习后再补充!

相关标签: java8新特性