Java的函數式接口及使用示例

Java 1.8加入了lambda表達式,可以進行函數式編程了,這幾天也一直在研究這個東西,從Java核心技術中得知java.util.function包中已經定義了許多常用的函數式接口。

書中也列舉了這個包下所有的接口,一共43個,有9個是通用接口,其餘34個均爲有關boolean、斷言、提供int、long、double三者的值以及處理int、long、double三者之間值相互轉換的一些接口。最後一個Runnable接口雖然沒有在java.util.function包下,但是符合函數式接口的定義。

下面是博主我根據這幾天理解寫的關於每個接口的理解以及接口內有些默認已經實現的方法的理解。最後精心設計了一個使用示例。

我們知道函數式接口就是僅僅只含有一個抽象方法的接口,可爲什麼還是要研究類庫中已經封裝好的接口呢?答案就是爲了提高編程統一率和效率。首先,如果是我們自己寫,這些接口對於我們來說是一種額外的工作,因此使用官方提供好的接口會提高開發效率;另外,官方提供的接口用的人比較多,這樣容易提高代碼轉手的難度,如果兩個人同時都學習了這一組接口,那麼當他們進行代碼交接的時候將會變得簡單許多。試想一下,如果我們自己寫這些通用接口,不同的人有不同的想法,他們起的名字就有可能不一樣,結果極有可能是不同的人開發出了不同的接口,卻實現了同樣的功能,當兩個人再次交接代碼時,無形增加了交接成本。

通用函數式接口有:

其他關於boolean、int、long、double類型的專用接口:

下面是所有的這43個接口的總覽:(java.util.function包中)

細心的童鞋們可能會注意到了在第一個列表最後一列還標註了一個其他方法。這些是在接口中就已經實現的方法,用於增強接口的功能,下面介紹幾個重要的方法。

1、andThen和compose

這兩個方法詳細請參考博主Lelontar的文章,他詳細講述了這兩個方法的理解以及用法。

2、and、or、negate、isEqual方法

這幾個方法是出現在和斷言相關的接口中,用於表示斷言的與、或、非以及元素與某值是否相等的關係。引用核心技術原文中的話,就是:

寫了一個示例如下:

public class Test2 {
	public static void main(String[] args) {
/*		// 提供100以內的整數供打印
		printRandom(5, () -> (int)(Math.random()*100));*/
		
/*		// 打印數組中每個元素的值,先用標準輸出打印,然後加上'@'符號後再次打印
		OperateEachNumberButNotReturn(new Integer[]{1,2,3,4,5},System.out::print,x -> System.out.println("@"+x));*/
		
/*		// 打印每相鄰兩元素的和
		OperateNearNumberButNotReturn(new Integer[]{1,2,3,4,5,6}, (x,y) -> System.out.print((x+y)+" "));*/
		
/*		Integer[] numbers = new Integer[]{1,2,3,4,5};
		// 給數組中的每一個元素加3後然後拼接@符號
		String[] result = OperateEachNumberAndReturn(numbers, (x) -> x+3+"@");
		System.out.println(Arrays.toString(result));*/
		
/*		// 每相鄰兩元素相加求和並返回詳細信息
		String[] result = OperateNearNumberAndReturn(new Integer[]{1,2,3,4,5,6}, (x,y) -> x+"+"+y+"="+(x+y));
		System.out.println(Arrays.toString(result));*/

/*		// 返回數組中每一個數字的相反數
		Integer[] result = CalculateEachNumberAndReturnUnary(new Integer[]{1,2,3,4,5,6}, x -> -x);
		System.out.println(Arrays.toString(result));*/
		
/*		// 每相鄰兩元素相加求和
		Integer[] result = CalculateNearNumberAndReturnBinary(new Integer[]{1,2,3,4,5,6}, (x,y) -> x+y);
		System.out.println(Arrays.toString(result));*/
		
/*		// 判斷數組中的每一個元素是否爲正數
		String[] result = predicateEachNumberArray(new Integer[]{1,2,3,4,5,6},"是個正數","不是個正數",x -> x>0 ? true : false);
		System.out.println(Arrays.toString(result));*/
		
/*		// 判斷數組中沒連續相鄰的兩個元素是否相等
		String[] result = predicateNearNumberArray(new Integer[]{1,2,4,4,5,6},"相等","不相等", (x,y) -> x == y);
		System.out.println(Arrays.toString(result));*/
	}
	
	/**
	 * 打印count個隨機整數,需要提供一個Supplier實現類
	 * @param count
	 * @param supplier
	 */
	public static void printRandom(int count,Supplier<Integer> supplier){
		for(int i=0;i<count;i++){
			System.out.println(supplier.get());
		}
	}
	
	/**
	 * 操作數組中每個元素的值,不會返回結果,需提供一個Consumer實現類
	 * @param numbers
	 * @param operator
	 */
	public static void OperateEachNumberButNotReturn(Integer[] numbers,Consumer<Integer> operator1,Consumer<Integer> operator2){
		for(int i=0;i<numbers.length;i++){
			operator1.andThen(operator2).accept(numbers[i]);
		}
	}
	
	/**
	 * 操作數組中每相鄰兩元素的值。不會返回結果,數組的索引必須大於等於2且爲偶數,需提供一個BiConsumer實現類
	 * @param numbers
	 * @param operator
	 */ 
	public static void OperateNearNumberButNotReturn(Integer[] numbers,BiConsumer<Integer, Integer> operator){
		for(int i=0;i<numbers.length/2;i++){
			operator.accept(numbers[i*2], numbers[i*2+1]);
		}
	}
	
	/**
	 * 操作數組中的每一個值,並返回String[]類型的結果,需提供一個Function實現類
	 * @param numbers
	 * @param operator
	 * @return
	 */
	public static String[] OperateEachNumberAndReturn(Integer[] numbers,Function<Integer, String> operator){
		String[] numbersString = new String[numbers.length];
		for(int i=0;i<numbers.length;i++){
			numbersString[i] = operator.apply(numbers[i]);
		}
		return numbersString;
	}
	
	/**
	 * 操作數組中每相鄰兩元素的值。並返回String[]類型的結果,數組的索引必須大於等於2且爲偶數,需提供一個BiFunction實現類
	 * @param numbers
	 * @param operator
	 * @return
	 */
	public static String[] OperateNearNumberAndReturn(Integer[] numbers,BiFunction<Integer, Integer, String> operator){
		String[] result = new String[numbers.length/2];
		for(int i=0;i<numbers.length/2;i++){
			result[i] = operator.apply(numbers[i*2], numbers[i*2+1]);
		}
		return result;
	}
	
	/**
	 * 操作數組中的每一個值,且返回相同類型的結果,需提供一個UnaryOperator實現類
	 * @param numbers
	 * @param operator
	 * @return
	 */
	public static Integer[] CalculateEachNumberAndReturnUnary(Integer[] numbers,UnaryOperator<Integer> operator){
		Integer[] result = new Integer[numbers.length];
		for(int i=0;i<numbers.length;i++){
			result[i] = operator.apply(numbers[i]);
		}
		return result;
	}
	
	/**
	 * 操作數組中每相鄰兩元素的值。且返回相同類型的結果,數組的索引必須大於等於2且爲偶數,需提供一個BinaryOperator實現類
	 * @param numbers
	 * @param operator
	 * @return
	 */
	public static Integer[] CalculateNearNumberAndReturnBinary(Integer[] numbers,BinaryOperator<Integer> operator){
		Integer[] result = new Integer[numbers.length/2];
		for(int i=0;i<numbers.length/2;i++){
			result[i] = operator.apply(numbers[2*i], numbers[2*i+1]);
		}
		return result;
	}
	
	/**
	 * 操作數組中的每一個元素,斷言它們
	 * @param numbers
	 * @param success 斷言成功後打印的字符串
	 * @param error 斷言失敗後打印的字符串
	 * @param predicate
	 * @return
	 */
	public static String[] predicateEachNumberArray(Integer[] numbers,String success,String error,Predicate<Integer> predicate){
		String[] result = new String[numbers.length];
		for(int i=0;i<numbers.length;i++){
			result[i] = predicate.test(numbers[i]) ? numbers[i]+success : numbers[i]+error;
		}
		return result;
	}
	
	/**
	 * 操作數組中的每連續的兩個相鄰元素,斷言它們
	 * @param numbers
	 * @param success 斷言成功後打印的字符串
	 * @param error 斷言失敗後打印的字符串
	 * @param predicate
	 * @return
	 */
	public static String[] predicateNearNumberArray(Integer[] numbers,String success,String error,BiPredicate<Integer, Integer> predicate){
		String[] result = new String[numbers.length/2];
		for(int i=0;i<numbers.length/2;i++){
			result[i] = predicate.test(numbers[2*i], numbers[2*i+1]) ? numbers[2*i]+"和"+numbers[2*i+1]+success : numbers[2*i]+"和"+numbers[2*i+1]+error;
		}
		return result;
	}
}

參考資料:Java核心技術第10版

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