這個系列主要羅列了 Java 8 的重要功能睛驳,并提供了此發(fā)行版中引入的示例。
Java SE 8 于 2014 年初發(fā)布粱甫,是目前在生產環(huán)境中使用最多波附,應用最廣發(fā)的版本艺晴。在 Java 8 中昼钻,最受關注的功能是 lambda 表達式。除此之外封寞,它還具有許多其它的功能然评,比如默認方法、流 API 和 新的日期/時間 API狈究。下面讓我們通過示例來了解 Java 8 中的這些新功能碗淌。
目錄
1.Lambda 表達式
2.功能接口
3.默認方法
4.流
5.日期/時間 API 更改
1.Lambda 表達式
Lambda 表達式對于使用 Scala 等其他流行語言的人并不陌生。在 Java 編程語言中抖锥,Lambda 表達式(或函數(shù))只是一個匿名函數(shù)亿眠,即不帶名稱且不受標識符限制的函數(shù)。它們只有在被需要的地方出現(xiàn)磅废,一般作為其他函數(shù)的參數(shù)纳像。
lambda 表達式的基本語法:
either
(parameters) -> expression
or
(parameters) -> { statements; }
or
() -> expression
典型的 lambda 表達式實例如下所示:
( x , y )-> x + y
請注意,根據(jù) x 和 y 的數(shù)據(jù)類型拯勉,方法可能在多個地方使用竟趾。參數(shù)可以匹配 int 、Integer 和 String宫峦。根據(jù)上下文岔帽,它將累加整數(shù)或連接兩個字符串。
編寫 Lambda 表達式的規(guī)則
1.Lambda 表達式可以具有零個导绷,一個或多個參數(shù)犀勒;
2.參數(shù)的類型可以顯示聲明,也可以從上下文推斷出來妥曲;
3.多個參數(shù)強制用小括號括起來贾费,并用逗號隔開¢苊耍空括號用于表示空參數(shù)集铸本;
4.當有單個參數(shù)時,如果推斷出類型遵堵,則不強制使用括號,例如 a -> return a*a
5.Lambda 表達式的主體可以包含零個怨规,一個或多個陌宿。
6.如果 Lambda 表達式的主體具有單個語句,則不必使用大括號波丰,并且匿名函數(shù)的返回類型與主體表達式的類型相同壳坪。如果主體中的語句超過一個,則必須用大括號括起來掰烟。
2.Functional interface
Functional interface 也稱為 單一抽象方法接口(SAM接口)爽蝴。顧名思義沐批,它們允許內部有一種抽象方法。Java 8 引入了一個新注解@FunctionalInterface蝎亚,當你的接口定義違反功能接口的約定時九孩,該注解可用于避免編譯時的錯誤。
典型的功能接口示例:
@FunctionalInterface
public interface MyFirstFunctionalInterface{
public void firstWork();
}
請注意发框,即使省略了 @FunctionalInterface 躺彬,功能接口依然有效。該注解僅用于通知編譯器在接口內部強制執(zhí)行單個抽象方法梅惯。另外宪拥,由于默認方法不是抽象的,因此可以隨意向功能接口添加任意數(shù)量的默認方法铣减。
要記住另一個重點她君,如果接口聲明的抽象方法覆蓋的公共方法之一(java.lang.Object),則該方法不會計入接口的抽象方法數(shù)量葫哗,因為該接口的任何實現(xiàn)都將具有來自 java.lang.Object
其他地方的實現(xiàn)缔刹。例如,下面是完全有效的功能接口魄梯。
@FunctionalInterface
public interface MyFirstFunctionalInterface{
public void firstWork();
@override
public String toString(); //Override from Object class
@override
public boolean equals(Object obj); //Override from Object class
}
3.Default Method
Java 8允許我們在接口添加非抽象方法桨螺,這些方法必須聲明為默認方法。Java 8中引入了默認方法以啟用 lambda 表達式的可能酿秸。
默認方法讓我們可以向庫的的接口添加新功能灭翔,并確保與較早版本編寫的代碼兼容。讓我們來看一個例子:
public interface Moveable {
default void move() {
System.out.println("I am moving!")
}
}
Moveable 接口定義了一種方法辣苏,move() 提供了默認實現(xiàn)肝箱。如果有任何類實現(xiàn)此接口,則無需實現(xiàn)它自己的 move() 方法版本稀蟋。它可以直接調用 instance.move() 煌张。例如:
public class Animal implements Moveable {
public static void main(String[] args) {
Animal tiger = new Animal();
tiger.move();
}
}
Output : I am moving
如果實現(xiàn)類想自定義 move() 方法的行為,那么它可以提供自己的自定義實現(xiàn)并覆蓋該方法退客。
4.Java 8 stream
Java 8 stream API 引入了另一個重要的變化骏融,它提供了一種以多種方式處理一組數(shù)據(jù)的機制,這些方式包括過濾萌狂、轉換等操作档玻。
Java 8中的 Stream API 支持不同類型的迭代,我們可以在其中簡單的定義要處理的數(shù)據(jù)項茫藏,對每個數(shù)據(jù)執(zhí)行操作误趴,并存儲操作的結果。
讓我們來看一個示例务傲。在這個示例中凉当,item
是String
類型的集合枣申,我們要刪除以某些文本開頭的item
。
List<String> items;
String prefix;
List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).collect(Collections.toList());
此處 item.stream()
表示我們希望item
使用Stream API處理列表中的數(shù)據(jù)看杭。
Java 8 Date/Time API 修改
新的 Date/Time API 類 (JSR-310)忠藤,也稱為 ThreeTen ,僅修改了在 Java 應用程序中處理日期的方式泊窘。
Date
Date
類基本已經過時了熄驼,取而代之的是LocalDate
、LocalTime
和 LocalDateTime
烘豹。
1.
LocalDate
僅代表一個日期瓜贾,既不是表示時間也沒有時區(qū);
2.LocalTime
僅代表一個時間携悯,既不是表示日期也沒有時區(qū)祭芦;
3.LocalDateTime
僅代表一個日期和時間,沒有時區(qū)憔鬼;
如果希望使用區(qū)域信息的日期功能龟劲,那么Lambda
為我們提供了三個額外的類來實現(xiàn),分別是OffsetDate
轴或、OffsetTime
和OffsetDateTime
昌跌。時區(qū)偏移可以用"+05:50"或"Europe/Paris"來表示,這需要用到ZoneId
類照雁。
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.of(12 , 20);
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZoneDateTime zoneDateTime = ZoneDateTime.now( ZoneId.of("Europe/Paris"));
Timestamp and Duration
為了隨時表示特定的時間戳蚕愤,我們需要使用類 Instant
。Instant
表示納秒級精度的瞬間時間饺蚊,支持包括與另一個Instant
比較以及增加或減少持續(xù)時間萍诱。
Instant instant = Instant.now();
Instant instant1 = instant.plus(Duration.ofMillis(5000));
Instant instant2 = instant.minus(Duration.ofMillis(5000));
Instant instant3 = instant.minusSecond(10);
Duration
類是Java語言首次帶來的全新概念,它表示兩個時間戳之間的差距污呼。
Duration duration = Duration.ofMillis(5000);
duration = Duration.ofSeconds(60);
duration = Duration.ofMinutes(10);
Duration
一般用于處理較小的的時間單位裕坊,例如毫秒、秒燕酷、分鐘和小時籍凝,所以它適合處理程序中的時間。如果是與人交互的持續(xù)時間苗缩,通常我們用 Period
類静浴。
Period period = Period.ofDays(6);
period = Period.ofMonths(6);
period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));
好了,本次分享就到這里挤渐,有任何問題歡迎在評論中留言。
全文畢
歡迎關注微信公眾號:Javall咖啡屋
每天更新各種互聯(lián)網技術(前后端双絮、數(shù)據(jù)庫浴麻、中間件得问、設計模式、數(shù)據(jù)結構软免、算法)學習心得體會