一起來學Java8(一)——函數式編程

在這篇文章中,我們將瞭解到在Java8下如何進行函數式編程。

函數式編程

所謂的函數式編程就是把函數名字當做值進行傳遞,然後接收方拿到這個函數名進行調用。

首先來看下JavaScript如何進行函數調用

var Person = {
    sayHello: function(name) {
        alert('hello ' + name);
    }
};

function work(fn) {
    fn('Jim');
}

work(Person.sayHello); // hello Jim

在這個例子中,sayHello函數被當做一個參數傳遞到另一個work函數當中,然後work調用給定的函數。

Java8中的函數式編程

在Java中,充當函數的角色是類中方法,在本篇文章當中提到的函數泛指方法。

接下來看下Java8中一個簡單的函數式編程例子:

import java.util.function.Consumer;

class Person {
    public static void sayHello(String name) {
        System.out.println("hello " + name);
    }
}

public class TestPerson {

	public static void main(String[] args) {
		work(Person::sayHello); // hello Jim
	}
	
	public static void work(Consumer<String> consumer) {
		consumer.accept("Jim");
	}
}

從這個例子中可以看到,Java8傳遞函數的方式跟JavaScript不一樣,在Java8當中傳遞函數的方式是:方法引用::方法名稱,如:String.valueOf,String.toString。接收參數Consumer可以先不用去了解,後面會講到。

爲了接收傳遞過來的函數引用,Java設計者提出了一個函數式接口的概念

函數式接口

函數式接口定義:一個接口裏面只有一個抽象方法

如下面幾個接口都是函數式接口:

  • Consumer
  • Supplier
  • Runnable
  • Callable

查看Runnable類的源碼可以發現,在類上方定義了一個@FunctionalInterface註解

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
  • @FunctionalInterface註解的作用:

當做一個標記使用,標記當前接口是一個函數式接口,如果你的接口有多個抽象方法或沒有抽象方法,那麼會編譯報錯。它的作用有點類似於@override註解,有輔助作用,但不是必須的。如果你想設計一個函數式接口,那麼最好把它加上。

// 編譯不通過,必須要有一個抽象方法
@FunctionalInterface
public interface InterfaceA {
	
}

// 編譯通過,只有一個抽象方法
@FunctionalInterface
public interface InterfaceB {
	void run();
}

// 編譯不通過,只能有一個抽象方法
@FunctionalInterface
public interface InterfaceC {
	void run();
	
	void run2();
}

// 編譯通過,run2是默認方法,並不是抽象方法
// 在這裏只有一個run抽象方法
@FunctionalInterface
public interface InterfaceD {
	void run();
	
	default void run2() {};
}

在例子InterfaceD中涉及到了接口默認方法default void run2() {};,這裏略過不講,後續文章中會有提到。

我們可以實現一個自定義的函數式接口,替代Consumer

// 自定義函數式接口
@FunctionalInterface
public interface FunctionCaller<T> {
	void call(T t);
}

public class TestPerson2 {

	public static void main(String[] args) {
		work(Person::sayHello);
	}
	
	public static void work(FunctionCaller<String> caller) {
		caller.call("Jim");
	}
}

小結

本篇主要講解了在Java8下如何進行函數式編程,以及如何定義和使用一個函數式接口。

歡迎關注作者微信公衆號:猿敲月下碼,第一時間獲得技術分享微信公衆號:猿敲月下碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章