【lambda】 java8 最显著的特性 lambda函数编程 数据和算法的分离

1 lambda 介绍

The most notable new feature in JDK 8 is the Lambda Expression, which provides a concise notation to construct an instance implementing a "Single-Abstract-Method Interface". In JDK 8, a "Single-Abstract-Method Interface" (i.e., an interface containing only one abstract method) is known as a "Functional Interface".

JDK 8 also retrofitted the Collection framework, with Lambda expression, functional interfaces and the introduction of streams API, to support chaining and aggregate operations (or filter-map-reduce) in functional programming.

举例1

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CounterLambda extends JFrame {
   JTextField tfCount;
   int count = 0;

   public CounterLambda() {
      Container cp = getContentPane();
      cp.setLayout(new FlowLayout());

      cp.add(new JLabel("Counter"));
      tfCount = new JTextField(count + "", 8);
      tfCount.setEditable(false);
      cp.add(tfCount);

      // Using an anonymous inner class as ActionEvent handler
      JButton btnUp = new JButton("Count Up");
      cp.add(btnUp);
      btnUp.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            tfCount.setText(++count + "");
         }
      });

      // Using a Lambda Expression to return an instance of ActionListener
      JButton btnDown = new JButton("Count Down");
      cp.add(btnDown);
      btnDown.addActionListener(e -> tfCount.setText(--count + ""));

      setSize(400, 100);
      setVisible(true);
   }
   public static void main(String[] args) {
      // Using Lambda Expression to return a Runnable instance
      SwingUtilities.invokeLater(() -> new CounterLambda());
   }
}

举例2 : Runnable Lambda

The Runnable interface contains a single abstract method, defined as follows:

@FunctionalInterface
public interface Runnable {
   void run();  // public abstract
}

We can create a Runnable object via anonymous inner class (Pre-JDK 8) or Lambda Expression (JDK 8), as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestRunnableLambda {
   public static void main(String[] args) {
      // Using an anonymous inner class
      Runnable r1 = new Runnable() {
         public void run() {
            System.out.println("Runnable 1");
         }
      };
      // Using a one-liner Lambda Expression for One-Method Interface
      Runnable r2 = () -> System.out.println("Runnable 2");

      r1.run();
      r2.run();
   }
}

举例 3: Functional Interface for Binary Operators

Let's define a Functional Interface to denote a binary operator (such as add or subtract), as follows:

@FunctionalInterface
public interface MyIntBinaryOperator {
   int applyAsInt(int left, int right);
}

In the following class, the method operate() takes 2 int's and an object of the above Functional Interface as parameters, and carries out the binary operation.

public class MyMathBinaryOperation {
   // Define instances of IntBinaryOperator for add, subtract, multiply and divide
   public MyIntBinaryOperator add = (a, b) -> a + b;
   public MyIntBinaryOperator sub = (a, b) -> a - b;
   public MyIntBinaryOperator mul = (a, b) -> a * b;
   public MyIntBinaryOperator div = (a, b) -> a / b;

   // Carry out the binary operation
   public int operate(int left, int right, MyIntBinaryOperator op) {
      return op.applyAsInt(left, right);
   }

   // Test Driver
   public static void main(String args[]){
      MyMathBinaryOperation op = new MyMathBinaryOperation();
      // Use pre-defined IntBinaryOperator
      System.out.println("8 + 9 = " + op.operate(8, 9, op.add));
      System.out.println("8 - 9 = " + op.operate(8, 9, op.sub));
      System.out.println("8 x 9 = " + op.operate(8, 9, op.mul));
      System.out.println("8 / 9 = " + op.operate(8, 9, op.div));
      // Use a custom IntBInaryOperator
      System.out.println("2 ^ 5 = " + op.operate(2, 5, (a, b) -> (int)Math.pow(a, b)));
   }
}

2 最核心的语法解释:

Syntax and Usage of Lambda Expressions

Prior to JDK 8, to construct an instance that implements a Functional Interface requires many lines of codes. Lambda Expression provides a shorthand notation. Moreover, you can pass a lambda expression as a method argument (treating code as data), as shown in the above example.

Lambda Expression defines the "sole" method of a Functional Interface. It consists of 2 parts: parameters and method body, separated by ->. The parameters are separated by commas and enclosed by parentheses. The parentheses can be omitted if there is only one parameter. The method body could be a statement or a block. The method name is omitted, as it is the sole abstract method of the Functional Interface. The parameters' type and the return type are also optional, as they can be inferred from the method signature.

The syntax is:

(arguments) -> (body)

For examples:

() -> statement    // No argument and one-statement method body

arg -> statement   // One argument (parentheses can be omitted) and method body 

(arg1, arg2, ...) -> { 
   body-block 
}   // Arguments separated by commas and block body

(Type1 arg1, Type2 arg2, ...) -> { 
   method-body-block;
   return return-value; 
}   // With arguments and block body

In other languages that support function variables or function objects (such as C++ and Python), Lambda is used to define an anonymous function. However, in JDK 8, Lambda expression is used to define the method implementation of an instance of a Single-Abstract-Method Interface?!

In fact, if you try to write:

int i = () -> 5;
// error: incompatible types: int is not a functional interface

But,

// Using Lambda expression to construct a Runnable instance.
// In other words, Lambda expression returns an instance of Function Interface
Runnable r1 = () -> System.out.println("run run()");
   // Runnable is a functional interface
   // Lambda expression is used to define the implementation of the abstract method run()

// Using Lambda expression to construct an ActionListener instance
ActionListener lis = e -> System.out.println("run actionPerformed()");

Java is an Object-oriented Programming language. Everything in Java are objects (except primitives for simplicity). Functions are not objects in Java (but part of an object), and hence, they cannot exist by themselves. Unlike other languages (such as C++, Python and JavaScript) functions can exist by themselves, and you can pass a function as a funtion's argument, and return a function from a funtion.

JDK 8's Functional Interface and Lambda Expression allow us to construct a "Function Object" in a one-liner (or a fewer lines of codes). However, it can be used only for objects with one method.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自驱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值