JDK_8新特性_Lambda表達式

Lambda 表達式基礎語法

  Lambda 表達式的基礎語法:
Java8中引入了一個新的操做符 "->" 該操做符稱爲箭頭操做符或 Lambda 操做符 箭頭操做符將 Lambda 表達式拆分紅兩部分: 左側:Lambda 表達式的參數列表 右側:Lambda 表達式中所需執行的功能, 即 Lambda 體 語法格式一:無參數,無返回值 () -> System.out.println("Hello Lambda!"); 語法格式二:有一個參數,而且無返回值 (x) -> System.out.println(x) 語法格式三:若只有一個參數,小括號能夠省略不寫 x -> System.out.println(x) 語法格式四:有兩個以上的參數,有返回值,而且 Lambda 體中有多條語句 Comparator<Integer> com = (x, y) -> { System.out.println("函數式接口"); return Integer.compare(x, y); }; 語法格式五:若 Lambda 體中只有一條語句, return 和 大括號均可以省略不寫 Comparator<Integer> com = (x, y) -> Integer.compare(x, y); 語法格式六:Lambda 表達式的參數列表的數據類型能夠省略不寫,由於JVM編譯器經過上下文推斷出,數據類型,即「類型推斷」 Comparator<Integer> com = (Integer x, Integer y) -> Integer.compare(x, y);

 

Lambda 表達式演變

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

public class TestLambda1 {

	private List<Apple> apples = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red"));


	/**
	 * 優化方式四:Stream API
	 */
	@Test
	public void Test4() {
		apples.stream()
			  .filter((a) -> a.getWeight() > 150)
			  .forEach(System.out::println);
	}

	/**
	 * 優化方式三:Lambda 表達式
	 */
	@Test
	public void Test3() {
		List<Apple> list1 = filterApples(apples, (Apple a) -> "green".equals(a.getColor()));
		list1.forEach(System.out::println);
		
		System.out.println("------------------------------------------");
		
		List<Apple> list2 = filterApples(apples, (Apple a) -> a.getWeight() > 150);
		list2.forEach(System.out::println);
	}

	/**
	 * 優化方式二:匿名內部類
	 */
	@Test
	public void Test2() {
		List<Apple> list = filterApples(apples, new ApplePredicate() {
			public boolean test(Apple apple){
				return "green".equals(apple.getColor());
			}
		});
		for (Apple apple : list) {
			System.out.println(apple);
		}
	}

	/**
	 * 優化方式一:策略設計模式
	 */
	@Test
	public void Test1() {
		List<Apple> list1 = filterApples(apples, new GreenApplePredicate()); 
		for (Apple apple : list1) {
			System.out.println(apple);
		}
		
		System.out.println("------------------------------------------");
		
		List<Apple> list2 = filterApples(apples, new HeavyApplePredicate()); 
		for (Apple apple : list2) {
			System.out.println(apple);
		}
	}


	public List<Apple> filterApples(List<Apple> apples, ApplePredicate p){
		List<Apple> result = new ArrayList<>();
		for(Apple apple : apples){
			if(p.test(apple)){
				result.add(apple);
			}
		}
		return result;
	} 

	@FunctionalInterface
	public interface ApplePredicate{
		public boolean test(Apple a);
	}
	public class GreenApplePredicate implements ApplePredicate{
		public boolean test(Apple apple){
			return "green".equals(apple.getColor());
		}
	}
	public class HeavyApplePredicate implements ApplePredicate{
		public boolean test(Apple apple){
			return apple.getWeight() > 150;
		}
	}
	
	/**
	 * 需求2:篩選超過150克的蘋果
	 * @param inventory
	 * @return
	 */
	public List<Apple> filterHeavyApples(List<Apple> inventory){
		List<Apple> result = new ArrayList<>();
		for (Apple apple: inventory){
			if (apple.getWeight() > 150) {
				result.add(apple);
			}
		}
		return result;
	} 

	/**
	 * 需求1:篩選綠色蘋果
	 * @param inventory
	 * @return
	 */
	public List<Apple> filterGreenApples(List<Apple> inventory){
		List<Apple> result = new ArrayList<>();
		for (Apple apple: inventory){
			if ("green".equals(apple.getColor())) {
				result.add(apple);
			}
		}
		return result;
	}

	/**
	 * Apple實體類
	 */
	public class Apple {
		private int weight = 0;
		private String color = "";

		public Apple(int weight, String color){
			this.weight = weight;
			this.color = color;
		}

		public Integer getWeight() {
			return weight;
		}

		public void setWeight(Integer weight) {
			this.weight = weight;
		}

		public String getColor() {
			return color;
		}

		public void setColor(String color) {
			this.color = color;
		}

		public String toString() {
			return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}';
		}
	}
}

 

Lambda 表達式須要「函數式接口」的支持

自定義函數式接口

import org.junit.Test;

public class TestLambda2 {
	
	/**
	 * 需求:對一個數進行運算
	 */
	@Test
	public void test(){
		System.out.println(operation(100, (x) -> x * x));
		System.out.println(operation(200, (y) -> y + 200));
	}
	
	public Integer operation(Integer num, MyFun fun){
		return fun.getValue(num);
	}
	
	/**
	 * 自定義接口函數
	 * 
	 * @FunctionalInterface:該註解用於編譯器校驗該函數接口是否合法即用於限制一個接口中只有一個抽象方法方法
	 */
	@FunctionalInterface
	public interface MyFun{
		public Integer getValue(Integer num);
	}
	
}

內置四大核心函數式接口

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.Test;

/**
 * Java8 內置的四大核心函數式接口
 * 
 * Consumer<T> : 消費型接口
 * 		void accept(T t);
 * 
 * Supplier<T> : 供給型接口
 * 		T get(); 
 * 
 * Function<T, R> : 函數型接口
 * 		R apply(T t);
 * 
 * Predicate<T> : 斷言型接口
 * 		boolean test(T t);
 * 
 */
public class TestLambda3 {

	/**
	 * Consumer<T> 消費型接口
	 */
	@Test
	public void test1(){
		print("Hello World!", (s) -> System.out.println(s));
	}

	// 需求:打印傳入的內容信息
	public void print(String str, Consumer<String> con){
		con.accept(str);
	}

	
	/**
	 * Supplier<T> 供給型接口
	 */
	@Test
	public void test2(){
		List<Integer> list = supplier(10, () -> (int)(Math.random() * 100));

		for (Integer i : list) {
			System.out.println(i);
		}
	}
	
	// 需求:產生指定個數的整數,並放入集合中
    public List<Integer> supplier(int len, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < len; i++) {
            list.add(sup.get());
        }
        return list;
    }
	

	/**
	 * Function<T, R> 函數型接口
	 */
	@Test
	public void test3(){
        String str = strHandler("abcdef", (s) -> s.toUpperCase());
        System.out.println(str);
	}
	
	// 需求:用於處理字符串
    public String strHandler(String str, Function<String, String> fun) {
        return fun.apply(str);
    }

    
	/**
	 * Predicate<T> 斷言型接口
	 */
	@Test
	public void test4(){
	    List<String> list = Arrays.asList("hello", "world", "Lambda", "www", "ok");
	    List<String> strList = filterStr(list, (s) -> s.length() > 3);
	    for (String str :strList) {
	        System.out.println(str);
	    }
	}
	
	// 需求:將知足條件的值,放入集合中
	public List<String> filterStr(List<String> list, Predicate<String> predicate) {
	    List<String> strlist = new ArrayList<>();
	    for (String str : list) {
	        if (predicate.test(str)) {
	            strlist.add(str);
	        }
	    }
	    return strlist;
	}

}

經常使用函數式接口

 

方法引用

import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Supplier;

import org.junit.Test;

/**
 * 1、方法引用:若 Lambda 體中的功能,已經有方法提供了實現,能夠使用方法引用
 * 			  (能夠將方法引用理解爲 Lambda 表達式的另一種表現形式)
 * 
 *  對象的引用 :: 實例方法名
 *  類名 :: 靜態方法名
 *  類名 :: 實例方法名
 * 
 * 注意:
 * 	 1. 方法引用所引用的方法的參數列表與返回值類型,須要與函數式接口中抽象方法的參數列表和返回值類型保持一致!
 * 	 2. 若Lambda 的參數列表的第一個參數,是實例方法的調用者,第二個參數(或無參)是實例方法的參數時,格式: ClassName::MethodName
 * 
 * 2、構造器引用 :構造器的參數列表,須要與函數式接口中參數列表保持一致!
 *  類名 :: new
 * 
 * 3、數組引用
 * 	類型[] :: new
 * 
 */
public class TestLambda4 {
	
	/**
	 * 數組引用
	 */
	@Test
	public void test5(){
		Function<Integer, String[]> fun1 = (args) -> new String[args];
		String[] strs1 = fun1.apply(10);
		System.out.println(strs1.length);
		
		System.out.println("--------------------------");
		
		Function<Integer, String[]> fun2 = String[] :: new;
		String[] strs2 = fun2.apply(20);
		System.out.println(strs2.length);
	}
	
	/**
	 * 構造器引用
	 */
	@Test
	public void test4(){
		Supplier<Apple> sup1 = () -> new Apple();
		System.out.println(sup1.get());
		
		System.out.println("------------------------------------");
		
		Supplier<Apple> sup2 = Apple::new;
		System.out.println(sup2.get());
		
		System.out.println("------------------------------------");
		
		Function<Integer, Apple> fun = Apple::new;
		System.out.println(fun.apply(100));
		
		System.out.println("------------------------------------");
		
		BiFunction<Integer, String, Apple> bfun = Apple::new;
		System.out.println(bfun.apply(90, "red"));
	}
	
	/**
	 * 類名 :: 實例方法名
	 */
	@Test
	public void test3(){
		BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
		System.out.println(bp1.test("abcde", "abcde"));
		
		System.out.println("-----------------------------------------");
		
		BiPredicate<String, String> bp2 = String::equals;
		System.out.println(bp2.test("abc", "abcd"));
		
		System.out.println("-----------------------------------------");
		
		Function<Apple, String> fun1 = (e) -> e.show();
		System.out.println(fun1.apply(new Apple()));
		
		System.out.println("-----------------------------------------");
		
		Function<Apple, String> fun2 = Apple::show;
		System.out.println(fun2.apply(new Apple()));
		
	}
	
	/**
	 * 類名 :: 靜態方法名
	 */
	@Test
	public void test2(){
		Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
		
		System.out.println("-------------------------------------");
		
		Comparator<Integer> com2 = Integer::compare;
	}
	
	/**
	 * 對象的引用 :: 實例方法名
	 */
	@Test
	public void test1(){
		Apple apple = new Apple(80,"green");
		
		Supplier<String> sup1 = () -> apple.getColor();
		System.out.println(sup1.get());
		
		System.out.println("----------------------------------");
		
		Supplier<String> sup2 = apple::getColor;
		System.out.println(sup2.get());
	}
	
	/**
	 * Apple實體類
	 */
	public class Apple {
		private int weight = 0;
		private String color = "";

		public Apple(){}
		
		public Apple(int weight){
			this.weight = weight;
		}
		
		public Apple(int weight, String color){
			this.weight = weight;
			this.color = color;
		}

		public Integer getWeight() {
			return weight;
		}

		public void setWeight(Integer weight) {
			this.weight = weight;
		}

		public String getColor() {
			return color;
		}

		public void setColor(String color) {
			this.color = color;
		}

		public String toString() {
			return "Apple{" + "color='" + color + '\'' + ", weight=" + weight + '}';
		}
		
		public String show() {
			return "測試方法引用!";
		}
	}
	
}
相關文章
相關標籤/搜索