1. 程式人生 > >java1.8-函式式(Functional)介面

java1.8-函式式(Functional)介面

什麼是函式(Functional)介面

l 只包含一個抽象方法的介面,稱為 函式式介面 l 你可以通過 Lambda 表示式來建立該介面的物件。(若 Lambda 表示式丟擲一個受檢 異常 ( 即:非執行時異常 ) 那麼該異常需要在目標介面的抽象方法上進行宣告)。 l 我們可以 一個 介面 上使用 @ FunctionalInterface 註解,這樣做可以檢查它是否是一個函式式 介面。同時 javadoc 也會包含一條宣告,說明這個介面是一個函式式
介面。 l java.util.function 包下定義了 java 8 的豐富的函式式介面 如何理解函式式介面

Java誕生日起就是一直倡導“一切皆物件”,在java裡面面向物件(OOP)程式設計是一切。但是隨著pythonscala等語言的興起和新技術的挑戰,java不得不做出調整以便支援更加廣泛的技術要求,也java不但可以支援OOP還可以支援OOF(面向函式程式設計)

在函數語言程式設計語言當中,函式被當做一等公民對待。在將函式作為一等民的程式語言中,Lambda表示式的型別是函式。但是Java8中,有所不同。在

Java8中,Lambda表示式是物件,而不是函式,它們必須依附於一類特別的物件型別——函式式介面

簡單的說,在Java8中,Lambda表示式就是一個函式式介面的例項。這就是Lambda表示式和函式式介面的關係。也就是說,只要一個物件是函式式介面的例項,那麼該物件就可以用Lambda表示式來表示。

所以以前用匿名內部類表示的現在都可以用Lambda表示式來寫。

Java 內建四大核心函式式介面

其它介面

package day26_1;

import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.Test;

/**
 * 函式式介面 : 只有一個抽象方法的介面, 關注的是方法的行為模式
 * Consumer<T> 消費器, 消費一個T型別的物件
 * 		void accept(T t); -> 有參無返回, 有輸入沒有輸出
 * 
 * Supplier<T> 供給器,返回一個T型別的物件
 * 		T get(); -> 無參有返回, 沒有輸入, 有輸出
 * 
 * Function<T, R> 轉換器, 輸入一個T型別的物件, 經過某種處理返回一個R型別的物件
 * 		R apply(T t); -> 有參有返回, 有輸入, 有輸出
 * 
 * Predicate<T> 斷定器 , 輸入一個T型別的物件, 經過某種判斷後返回真或假
 * 		boolean test(T t); -> 有參有固定的返回型別(boolean) 
 * 
 * BinaryOperator<T> 二元運算操作, 輸入2個T型別的物件, 經過某種處理後返回一個T型別的物件
 * 		T apply(T t1, T t2);
 * 
 * 方法引用 : 適用於方法的模式一樣, 有幾個輸入, 有沒有輸出。
 */
public class FunctionalInterfaceTest {
	
	@Test
	public void test9() {
		Supplier<Student> supplier1 = () -> new Student();
		Supplier<Student> supplier2 = Student::new; // 構造器引用
		
		System.out.println(supplier2.get());
	}
	
	@Test
	public void test8() {
		new Supplier<Double>() {
			@Override
			public Double get() { // 無參有返回
				return Math.random();
			}
		};
		// lambda表示式
		Supplier<Double> supplier1 = () -> Math.random();
		// 方法引用
		Supplier<Double> supplier2 = Math::random;
		
		System.out.println(supplier1.get());
		System.out.println(supplier2.get());
	}
	
	@Test
	public void test7() {
		new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println(t);
			}
		};
		Consumer<String> consumer1 = t -> System.out.println(t);
		Consumer<String> consumer2 = System.out::println; // ::表示類或物件的方法
	}
	
	@Test
	public void tes6() {
		// 獲取兩個學生中分數最高的。
		BinaryOperator<Student> binaryOperator = (t1, t2) -> t1.getScore() > t2.getScore() ? t1 : t2;
		Student s1 = new Student(1, "小明", 3, 50);
		Student s2 = new Student(2, "小麗", 2, 80);
		
		Student apply = binaryOperator.apply(s1, s2);
		System.out.println(apply);
	}
	@Test
	public void test5() {
		BinaryOperator<String> binaryOperator = new BinaryOperator<String>() {
			@Override
			public String apply(String t, String u) {
				return t + u;
			}
		};
		
		String apply = binaryOperator.apply("safljsfljk", "xxxxx191923");
		System.out.println(apply);
		
		BinaryOperator<String> binaryOperator2 = (t1, t2) -> t1 + t2;
		String apply2 = binaryOperator2.apply("a324234", "我是漢字");
		System.out.println(apply2);
	}
	
	@Test
	public void test4() {
		Predicate<String> predicate1 = new Predicate<String>() {
			@Override
			public boolean test(String t) {
				return t.endsWith(".java");
			}
		};
		boolean test1 = predicate1.test("hello.abc");
		System.out.println(test1);
		
		// lambda表示式
		Predicate<String> predicate2 = t -> t.endsWith(".java");
		boolean test2 = predicate2.test("hello.java");
		System.out.println(test2);
	}
	
	
	@Test
	public void test3() {
		Function<Double, Integer> function1 = new Function<Double, Integer>() {
			@Override
			public Integer apply(Double t) {
				return t.intValue();
			}
		};
		
		Integer num1 = function1.apply(3.94159);
		System.out.println(num1);
		
		// lambda 表達 
		Function<Double, Integer> function2 = t -> t.intValue(); 
		Integer num2 = function2.apply(9.2324);
		System.out.println(num2);
	}
	
	@Test
	public void test2() {
		Supplier<Integer> supplier1 = new Supplier<Integer>() {
			@Override
			public Integer get() {
				return 200;
			}
		};
		
		Integer integer = supplier1.get();
		System.out.println(integer);
		
		Supplier<Integer> supplier2 = () -> 200;
		Integer integer2 = supplier2.get();
		System.out.println(integer2);
	}
	
	@Test
	public void test1() {
		Consumer<String> consumer = new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println(t);
			}
		};
		
		consumer.accept("afljaslfjalksjf");
		
		Consumer<Integer> consumer2 = t -> System.out.println(t);
		consumer2.accept(234238); // 消費器
		
	}
}

package day26_1;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.Test;

public class FunctionalInterfaceExer {
	
	@Test
	public void exer4() {
		// 寫一個判定器, 輸入一個學生物件, 判定他是否及格了。
		Predicate<Student> predicate1 = new Predicate<Student>() {
			@Override
			public boolean test(Student t) {
				return t.getScore() >= 60;
			}
		};
		Student student = new Student(1, "小明", 5, 1.5);
		boolean test = predicate1.test(student);
		System.out.println(test);
		
		// Lambda表示式
		Predicate<Student> predicate2 = t -> t.getScore() >= 60;
		System.out.println(predicate2.test(student));
	}
	
	@Test
	public void exer3() {
		// 寫一個轉換器, 把學生物件轉換成一個Double
		Function<Student, Double> fun1 = new Function<Student, Double>() {
			@Override
			public Double apply(Student t) {
				return t.getScore();
			}
		};
		Student student = new Student(1, "小明", 5, 80.5);
		Double apply = fun1.apply(student);
		System.out.println(apply);
		
		// lambda表示式
		Function<Student, Double> fun2 = t -> t.getScore();
		Double apply2 = fun2.apply(student);
		System.out.println(apply2);
	}
	
	// 做一個練習 : 使用供給器獲取一個Student物件, 再使用消費型器這個物件列印輸出。
	@Test
	public void exer2() {
		Supplier<Student> supplier1 = new Supplier<Student>() {
			@Override
			public Student get() {
				return new Student();
			}
		};
		
		Student student = supplier1.get();
		Consumer<Student> consumer1 = new Consumer<Student>() {
			@Override
			public void accept(Student t) {
				System.out.println(t);
			}
		};
		consumer1.accept(student);
		
		// lambda表示式
		Supplier<Student> supplier2 = () -> new Student();
		Student student2 = supplier2.get();
		Consumer<Student> consumer2 = t -> System.out.println(t);
		consumer2.accept(student2);
		
	}
	
	@Test
	public void exer1() {
		// 做一個供給器, 每呼叫一次獲取一個隨機100以內的整數。
		Supplier<Integer> supplier1 = new Supplier<Integer>() {
			@Override
			public Integer get() {
				return (int)(Math.random() * 100);
			}
		};
		
		Integer num = supplier1.get();
		System.out.println(num);
		
		// lambda表示式
		Supplier<Integer> supplier2 = () -> (int)(Math.random() * 100);
		
		Integer num2 = supplier2.get();
		System.out.println(num2);
	}
}

相關推薦

java1.8-式式(Functional)介面

什麼是函式式(Functional)介面 l 只包含一個抽象方法的介面,稱為 函式式介面 。 l

Java 8 式式介面 : Supplier、Function、Consumer、Predicate

函式式介面特點 1、三種方法 唯一的抽象方法 使用default定義普通方法(預設方法),通過物件呼叫。 使用static定義靜態方法,通過介面名呼叫。 2、一個新註解@FunctionInterface 如果某一個介面就是為了函式式介面而生的,使用註解@F

Java 8 式式介面,Function,Consumer,Predicate 介面的學習

void accept(T t); 2.1 使用     還是如上的例子,Demo程式碼如下: public class Test { public static void main(String[] args) throws InterruptedException {

Java 8 式式介面

函式式介面:由@FunctionalInterface註解,簡稱FI。其中有且只有一個自己獨有的抽象方法,不包括從上級繼承過來的方法。其中可以有多個預設方法和靜態方法例如:@FunctionalInte

keras:2)式式(Functional)模型

相對序貫模型,函式式模型顯得更靈活(序貫是函式式的特例),這裡對函式式模型進行簡單地介紹,具體可以參考官方網站。 官方的栗子: from keras.layers import Input, Dense from keras.models import Model # This

java1.8新特性之介面定義增強

本篇重點:使用default和static定義介面方法 從java發展之初到今天已經經過了20多年的時間了,在這20多年的時間裡所有的java開發者都知道java中的介面是由全域性常量和抽象方法組成。但是從jdk1.8的時代這一組成改變了。 為什麼會改變

java1.8獲取類和介面函式引數名稱

程式碼如下 package js.oop.parameter; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.Arrays; /** * j

Java8 Lambda( -> )&&方法引用( :: )&&式式介面(@Functional)

一、簡述 Java8之前建立一個執行緒的程式碼: new Thread(new Runnable() { @Override public void run() { System.out.println("Test");

Java 8 常見式式介面使用簡單示例

簡介 JDK 1.8 API包含了很多內建的函式式介面。之所以提供這些介面,是因為它們有比較多的使用場景,通過結合使用lambda表示式,我們可以很方便地利用這些介面將一些邏輯作為變數傳遞甚至組合起來實現更為複雜的邏輯,就像我們將一些普通類物件作為變數傳遞或者組合起來一樣方便。

Java 8 新增式式介面到底是什麼?

Java 8 新增函式式介面到底是什麼? 從 Java 8 開始便出現了函式式介面(Functional Interface,以下簡稱FI) 定義為: 如果一個介面只有唯一的一個抽象介面,則稱之為函式式介面。為了保證介面符合 FI ,通常會在介面類上新增 @FunctionalI

jdk1.8新特性 式式介面

函式式介面    1、只包含一個抽象方法的介面,稱為函式式介面。    2、你可以通過Lambda 表示式來建立該介面的物件。(若Lambda 表示式丟擲一個受檢異常,那麼該異常需要在目標介面的抽象方法上進行宣告)。    3、我們可以在任意函式式介面上使用@Function

Java 8中一些常用的全新的式式介面

函式式介面 什麼是函式式介面? 函式式介面,@FunctionalInterface,簡稱FI,簡單的說,FI就是指僅含有一個抽象方法的介面,以@Functionalnterface標註,注意⚠️,這裡的抽象方法指的是該介面自己特有的抽象方法,而不包含它從其

java8新增特性(二)----式式介面Functional

     上一篇部落格介紹了java8新增的Lambda表示式,這一節介紹一下java8的函數語言程式設計,兩者之間有什麼聯絡呢?請往下看~~~      Lambda表示式如何在java型別中表示的呢?      語言設計者投入了大量的精力來思考如何使現有的函式友好地支

8000字長文讓你徹底瞭解 Java 8 的 Lambda、式式介面、Stream 用法和原理

> 我是風箏,公眾號「古時的風箏」。一個兼具深度與廣度的程式設計師鼓勵師,一個本打算寫詩卻寫起了程式碼的田園碼農! 文章會收錄在 [JavaNewBee](https://github.com/huzhicheng/JavaNewBee) 中,更有 Java 後端知識圖譜,從小白到大牛要走的路都在裡面。公眾號

第三章(2) JAVA8 api為我們提供的式式介面

   咱們書接上回,上回咱們說到,Java 8的庫設計師幫你在java.util.function包中引入了幾個新的函式式介面。我們接下來會介紹Predicate、Consumer和Function。     1.Predicate(謂詞)

/*Java8內建的四大核心式式介面

package com.greatest.Java8; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import ja

java8--式式介面

java8中內建了很多介面 ,它們都標記了@FunctionalInterface註解,FunctionalInterface是個無任何抽象方法的介面。Java8試圖闡明,當一個介面被標記上FunctionalInterface,那麼它應該被開發者注意:這是個函式式介面,應該用lambda表示其

【Keras入門日誌(3)】Keras中的序貫(Sequential)模型與式式Functional)模型

【時間】2018.10.31 【Keras入門日誌(3)】Keras中的序貫(Sequential)模型與函式式(Functional)模型 概述 本文主要介紹了Keras中的序貫(Sequential)模型與函式式(Functional)模型的基本使用方法,並在各部分的最後提供了一些具

初識Lambda表示式2(JDK提供的式式介面的引出)----java

一個小栗子    為了更加深刻的理解lambda表示式,寫了如下一個栗子: package com.nrsc.lambda.MoneyDemo; import java.text.DecimalFormat; @FunctionalInterface inte

初識Lambda表示式3----JDK提供式式介面的引出2---java

寫在前面的話     總感覺上篇部落格有些東西需要補充,於是思來想去寫下了本篇部落格… 1.場景引入     場景: 假如有這樣一種場景,我們的專案裡有好多方法,這些方法的引數都包含一個介面,這些介面雖然其功能各不相同,但是卻都有一個共同點