Java 8 函数式编程

一、面向对象编程 & 函数式编程

面向对象编程是对数据进行抽象,而函数式编程是对行为进行抽象。现实世界中,数据和行为并存,程序也是如此,因此这两种编程方式我们都得学。

二、Java 8 Lambda表达式

Java 8 的最大变化是引入了Lambda表达式——一种紧凑、传递行为的方式。
Android为按钮控件绑定事件的五种方式中有一种是使用匿名内部类的方式,
步骤1.首先需要获取到 layout 中布局页面的Button控件中指定的Id:
步骤2.之后为这样按钮绑定监听器,使用匿名内部类的方式,代码如下:

button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {    
           @Override
            public void onClick(View view) {
                    Toast.makeText(MainActivity.this, "按钮被点击了",Toast.LENGTH_SHORT).show();      
            }
        });

在这个例子中,我们创建了一个新对象,它实现了OnClickListener接口。这个接口只有一个方法onClick,当用户点击屏幕上的按钮时,button就会掉用这个方法。匿名内部类实现了该方法。

/**
     * Interface definition for a callback to be invoked when a view is clicked.
     */
    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }
这实际上是一个代码即数据 的例子——我们给按钮传递了一个代表某种行为的对象

设计匿名内部类的目的,就是为了方便Java程序员将代码作为数据传递。不过,匿名内部类还是不够简便。为了调用一行重要的逻辑代码Toast.makeText,不得不加上4行冗繁的样板代码。尽管如此,样板代码并不是唯一的问题:这些代码还相当难读,因为它没有清楚地表达程序员的意图。我们并不想传入对象,只想传入行为。在Java 8 中,上述代码可以写成一个Lambda表达式

 button.setOnClickListener(view -> Toast.makeText(MainActivity.this, "按钮被点击了",Toast.LENGTH_SHORT).show());

使用Lambda表达式将行为和按钮点击进行关联

和传入一个实现某接口的对象不同,我们传入了一段代码块——一个没有名字的函数。view是参数名,和上面匿名内部类示例中的是同一个参数。->将参赛和Lambda表达式的主题分开,而主体是用户点击按钮时会运行的一些代码。
Lambda表达式除了基本的形式之外,还有几种变体,如

//无参数
Runnable noArguments = () -> System.out.println("Hello World");

//一个参数
ActionListener onArguments = event -> System.out.println("button clicked");

//Lambda表达式是一段代码块
Runnable multiStatement = () ->{
       System.out.print("Hello");
       System.out.println("World");
}

//表示包含多个参数的方法
BinaryOperator  add = (x,y) -> x + y;

//显示声明参数类型
BinaryOperator  addExplicit = (Long x, Long y) -> x + y;

三、 Lambda表达式只能针对函数式接口使用

函数式接口

当接口里只有一个抽象方法的时候,就是函数式接口,可以使用注解(@FunctionalInterface)强制限定接口是函数式接口,即只能有一个抽象方法。
例如:

public interface Integerface1 {
     void test();
}

上面的接口只有一个抽象方法,则默认是函数式接口。

interface Integerface3 {
     void test();
     void test2();
}

该接口有两个抽象方法,不是函数式接口

@FunctionalInterface
interface Integerface2 {
}

上面这样写编译会报错,因为@FunctionalInterface注解声明了该接口是函数式接口,必须且只能有一个抽象方法。
如:

@FunctionalInterface
interface Integerface2 {
     void test();
}

参考文章
java8新特性之函数式接口、lambda表达式、接口的默认方法、方法和构造函数的引用

你可能感兴趣的:(Java 8 函数式编程)