1. 程式人生 > >(一)lambda表示式

(一)lambda表示式

學習記錄《寫給大忙人的java_SE8》。

先上一個我們平時用到的集合排序:這裡提供了4種方法

                List<String> list = new ArrayList<>();
		list.add("new world");
		list.add("hello");
		//匿名內部類
		Collections.sort(list, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return Integer.compare(o1.length(), o2.length());
			}
		});
		//常規lambda
		Collections.sort(list, (s1, s2) -> s1.compareToIgnoreCase(s2));
		//lambda方法引用
		Collections.sort(list, String::compareToIgnoreCase);
		//Comparator介面靜態方法+方法引用
		Collections.sort(list, Comparator.comparing(String::length));
		list.forEach(System.out::println);

1.1 語法

引數+箭頭+表示式

例如:

Comparator<? super String> com=(String s1,String s2)->Integer.compare(s1.length(),s2.length());

a,如果沒有引數,使用()

b,如果不是一個簡單表示式可以解決的,用{}將表示式程式碼包裹起來

c,引數有時可以省略型別(見上圖),程式會自動推斷型別,建議還是寫上,方便閱讀

d,引數可以使用final等修飾,也可以使用註解修飾

1.2 函式式介面

定義:只含一個【抽象】方法的介面。任何一個lambda表示式都可以轉換成使用的API中對應的函式式介面。

物件和類的管理完全依賴於如何實現,比傳統的內部類效率高。

雖然Object是所有類的基類,但它不是函式式介面。

1.3 方法引用

a,類::靜態方法 b,物件::例項方法 上面2種等價於使用引數的lambda表示式 c,類::例項方法 上面第一個引數成為呼叫方法的物件如String::compareToIgnoreCase等價於x.compareToIgnoreCase(y)

1.4 構造器引用

格式:類名::new

		List<String> labels = new ArrayList<>();
		Stream<Button> stream = labels.stream().map(Button::new);
		Button[] buttons = stream.toArray(Button[]::new);

如上,陣列構造器引用可以繞過java中的一個限制:不能使用(new)泛型陣列(泛型擦除)

可以看到,傳入Button陣列構造器引用,返回一個Button陣列,而用list.toArray等方法返回的是Object陣列

1.5 變數作用域 lambda表示式構成:一段程式碼;引數;【自由變數的值】:自由指的是不是引數又沒有在表示式中定義的變數 lambda表示式可以捕獲閉包(含有自由變數的程式碼塊)中的變數值,需要遵守一個約束:被引用的變數的值不可以被更改(執行緒安全考慮) java8之前,內部類只允許訪問final的區域性變數,為了適應lambda表示式,規則放寬為:可以訪問任何【有效】final的區域性變數,即值不會發生改變的變數(應該是編譯期檢查) 同時注意,不要指望編譯器捕獲所有併發訪問錯誤,不可變約束只作用在區域性變數上,如果是例項或靜態變數,編譯器不會報錯。 lambda表示式中的this關鍵詞和其他地方意義一樣。

1.6 預設方法 如果一個類有多個父類/實現介面,而父類/介面中的方法名和引數衝突 a,如果父類提供具體實現,實現的介面中預設方法會被忽略(類優先原則,向後相容性) b,如果只實現2個或多個介面,它們的某個方法的方法名和引數都衝突。如果一個介面提供的是預設方法,不管其他介面是抽象還是預設方法,此類必須覆蓋這個方法;

1.7 靜態方法

java8也開啟了介面靜態方法的大門。比如Collections的nCopies方法如果放進List中,就可以使用List直接呼叫此方法,而不用Collections了。

前面提到過靜態方法,如

Comparator.comparing(String::length)

這種方式返回一個比較器是很簡潔的。