Java8的幾個(gè)重要特性介紹

Java8的新特性有很多,只對(duì)代表性的四個(gè)重要特性做一次總結(jié),方便以后回顧。

Java8的四個(gè)重要新特性:

1. Lambda;

2. 方法引用;

3. 默認(rèn)方法;

4. Stream。

1、 Lambda

Lambda表達(dá)式:Lambda可以讓函數(shù)當(dāng)做一個(gè)方法的參數(shù)進(jìn)行傳遞,并且讓代碼變得更加簡潔。Lambda表達(dá)式省去了匿名類的麻煩,但Lambda只能給包含一個(gè)方法的接口定義,且Lambda的入?yún)⒑头祷刂当仨毢徒涌谥械姆椒ㄒ恢隆?/p>

語法:

(type param1, type param2…) -> { Statements }

Lambda幾個(gè)特性:

1. 參數(shù)類型可選:編譯器可以自動(dòng)識(shí)別參數(shù)的類型;

2. 參數(shù)圓括號(hào)可選:只有一個(gè)參數(shù)時(shí),可省略圓括號(hào);

3. 語句塊大括號(hào)可選:只有一個(gè)語句時(shí),可省略大括號(hào);

4. 返回值可選:只有一個(gè)語句時(shí),可省略返回值。

這四個(gè)特性,兩個(gè)針對(duì)參數(shù),兩個(gè)對(duì)應(yīng)語句塊,很好理解,代碼分析如下:

public class LambdaTest3 {

? ? ? ? public static void main(String[] args) {

/** * 類型聲明,圓括號(hào),大括號(hào)的省略情況*/

// 先看參數(shù)部分,主要看類型聲明和括號(hào)的省略情況

// 1.參數(shù)類型聲明可選

// 2.一個(gè)參數(shù)時(shí),括號(hào)可選

// 兩個(gè)參數(shù),沒有省略時(shí)

MathOperate1 mathOperate1_1 = (int a, int b) -> {

System.out.println("two parameter");

return a + b;

};

mathOperate1_1.operate(12, 45);

// 兩個(gè)參數(shù),省略參數(shù)類型聲明

MathOperate1 mathOperate1_2 = (a, b) -> {

System.out.println("two parameter");

return a + b;};

mathOperate1_2.operate(12, 45);

// 一個(gè)參數(shù),帶類型聲明,必須有括號(hào)

MathOperate2 mathOperate2_1 = (int a) -> {

System.out.println("one parameter");

return a;

};

mathOperate2_1.operate(8);

// 一個(gè)參數(shù),省略類型聲明

MathOperate2 mathOperate2_2 = (a) -> {

System.out.println("one parameter");

return a;

};

mathOperate2_2.operate(8);

// 一個(gè)參數(shù),省略括號(hào),必須同時(shí)省略類型聲明

MathOperate2 mathOperate2_3 = a -> {

System.out.println("one parameter");

return a;

};

mathOperate2_3.operate(8);

// 無參數(shù),不可省略括號(hào)

MathOperate3 mathOperate3_1 = () -> {

System.out.println("no parameter");

return -1;

};

mathOperate3_1.operate();

// 語句塊部分

// 1.一條語句,可省略大括號(hào)

// 2.一條語句,未省略大括號(hào),有返回值,則必須要return關(guān)鍵字

// 多條語句,有返回值,不能省略大括號(hào),不能省略return,若無返回值則不需要return MathOperate1 operate1 = (a, b) -> {

int c;return c = a + b;

};

operate1.operate(8, 8);

// 一條語句,有返回值,有大括號(hào),則必須有return

MathOperate1 operate2 = (a, b) -> {

return a + b;

};

operate2.operate(8, 8);

// 一條語句,沒有返回值,有大括號(hào)時(shí),不需要return

MathOperate4 operate3 = (a, b) -> {

int c = a + b;

};

operate3.operate(8, 8);

// 一條語句,省略大括號(hào)和return關(guān)鍵字,如果有返回值,表達(dá)式結(jié)果默認(rèn)為返回值

MathOperate1 operate4 = (a, b) -> a + b;

operate4.operate(8, 8);

}

// 兩個(gè)參數(shù)

@FunctionalInterfaceinterface

MathOperate1 { int operate(int a, int b);

}

// 一個(gè)參數(shù)

@FunctionalInterfaceinterface

MathOperate2 {

int operate(int a);

}

// 無參數(shù)

@FunctionalInterfaceinterface

MathOperate3 {

int operate();

}

// 無返回值

@FunctionalInterfaceinterface

MathOperate4 {

void operate(int a, int b);

}}

另外,Lambda主體部分可能使用外部的變量,當(dāng)Lambda要使用外部的變量時(shí),其內(nèi)部不能修改外部變量的值。

public class LambdaTest2 {

public static void main(String[] args) {

/** * 作用域問題 */

// 引用一個(gè)塊外部的變量,在內(nèi)部不能修改它的值

int c = 12;

test2(56, 45, (a, b) -> {

a += 2;b += 2;

int d = a + b + c;

System.out.println(d);});

}

private static void test2(int a, int b, LambdaTestInterface2 lam2) {

lam2.init(a, b);

}

public interface LambdaTestInterface2 {

void init(int a, int b);

}

}

如何理解java 8中引入的Lambda表達(dá)式?匿名類,從這里著手看看,在此之前,接口對(duì)象,可用匿名類實(shí)例化。而Lambda可以理解為接口的另一種實(shí)例化的方法,但前提是這個(gè)接口只能有一個(gè)抽象方法。

public class LambdaTest {

public static void main(String[] args) {

// TODO Auto-generated method stub

/** * lambda和匿名類的對(duì)比 */

// 匿名類的寫法,當(dāng)參數(shù)使用

int result1 = operation(8, 8, new MathOperate() {

@Override

public int operate(int a, int b) {

return a + b;

}});

// lambda,同樣當(dāng)參數(shù)使用

int result2 = operation(8, 8, (a, b) -> a + b);

System.out.println(result1);

System.out.println(result2);

}

private static int operation(int a, int b, MathOperate mathOperate) {

return mathOperate.operate(a, b);

}

@FunctionalInterfaceinterface

MathOperate {

int operate(int a, int b);

}

}

2、 方法引用

使用“::”進(jìn)行方法引用,按引用的方法分三類:

1. 靜態(tài)方法;

2. 構(gòu)造方法;

3. 成員方法。

引用靜態(tài)方法,類名::方法名。方法參數(shù)和返回值需要和接口中的一致;引用構(gòu)造函數(shù),類名::new。構(gòu)造函數(shù)需要和接口中參數(shù)一致;引用對(duì)象方法,對(duì)象::方法名。方法參數(shù)和返回值需要和接口中的一致,不能通過對(duì)象引用靜態(tài)方法。

public class MethodJava8 {

public static void main(String[] args) {

/** * 方法引用 */

// ::可以引用靜態(tài)方法,對(duì)象的方法或構(gòu)造函數(shù)

// 1.靜態(tài)方法引用,引用方法的形參和返回值,需和接口中的一致

Convertconvert = Integer::valueOf;System.out.println(convert.convert("888"));

// 匿名類的方法實(shí)現(xiàn)

Convertconvert2 = new Convert() {

@Override

public Integer convert(String t1) {

// TODO Auto-generated method stubreturn Integer.valueOf(t1);

}

};

System.out.println(convert2.convert("999"));

// 引用自定義類的靜態(tài)方法

Convertconvert3 = MyConvert::convert;System.out.println(convert3.convert("101010"));

// 2.引用對(duì)象中的方法,靜態(tài)方法不能通過對(duì)象引用

MyConvert myConvert = new MethodJava8.MyConvert();

//引用對(duì)象的成員方法

Convertconvert4 = myConvert::convert2;

// Convertconvert4 = myConvert::convert; //錯(cuò)誤,不能引用靜態(tài)方法System.out.println(convert4.convert("111111"));

// 3.引用User的構(gòu)造函數(shù)

UserFactoryuserfactory = User::new;User user = userfactory.create("Test2", 22, "male");

System.out.println(user.getName());

// 匿名類實(shí)現(xiàn)

UserFactoryUserFactoryuserfactory2 = new UserFactory() {

@Override

public User create(String name, int age, String gendle) {

return new User(name, age, gendle);

}

};

System.out.println(userfactory2.create("Test1", 11, "female").getName());

}

@FunctionalInterfaceinterface

Convert{T2 convert(T1 t1);

}

interface UserFactory {

U create(String name, int age, String gendle);

}

public static class MyConvert {

public static Integer convert(String t1) {

// TODO Auto-generated method stub

return Integer.valueOf(t1);

}

public Integer convert2(String t1) {

return Integer.valueOf(t1);

}

}

}

3. 默認(rèn)方法

在接口的方法前加default關(guān)鍵字,表示一個(gè)默認(rèn)方法,加static表示默認(rèn)靜態(tài)方法。有了默認(rèn)方法,在需求變更的時(shí)候,不必因增加接口中的方法,而需要重新實(shí)現(xiàn)已經(jīng)實(shí)現(xiàn)該接口的類。

public class DefaultMethod {

public static void main(String[] args) {

// TODO Auto-generated method stub

/** * 默認(rèn)方法 */

MyDefaultMethodTest.operate();

MyDefaultMethodTest myDefaultMethodTest = new MyDefaultMethodTest() {};

myDefaultMethodTest.init();

}

public interface MyDefaultMethodTest {

// 默認(rèn)方法

default void init() {

System.out.println("It is init() in MyDefaultMethodTest");

}

//默認(rèn)靜態(tài)方法,不能通過對(duì)象訪問

static void operate() {

System.out.println("It is operate() in MyDefaultMethodTest");

}

}

}

4、 Stream

Stream,類似把操作的對(duì)象看成一個(gè)數(shù)據(jù)流,對(duì)它操作后會(huì)返回被處理后的流,可以繼續(xù)操作,比如排序,過濾,變換等等。

1. 數(shù)據(jù)流的生成集合,數(shù)組,IO,產(chǎn)生器等;

2. 數(shù)據(jù)流操作foreach,map,filter,limit,sorted,parallel等。

public class StreamJava8 {

public static void main(String[] args) {

// TODO Auto-generated method stub

/** * 創(chuàng)建Stream流 */

List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");

List<String> filtered1 = list.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

/** * 聚合操作 */

// foreach

filtered1.forEach(s -> System.out.println(s));

System.out.print("\n");

// map

List<Interge> mapNumbers = Arrays.asList(11, 2, 2, 6, 4, 3, 9);

List<Interge> mapResult = mapNumbers.stream().map(a -> a * a).distinct().collect(Collectors.toList());

mapResult.forEach(System.out::println);

System.out.print("\n");

// filter

List<Interge> filterNumbers = Arrays.asList(11, 2, 2, 6, 4, 3, 9);

List<Interge> filterResult = filterNumbers.stream().filter(a -> a > 5).collect(Collectors.toList());

filterResult.forEach(System.out::println);

System.out.print("\n");

// limit

List<String> limitStr = Arrays.asList("a", "b", "c", "d", "e", "f");

List<String> limitResult = limitStr.stream().limit(2).collect(Collectors.toList());

limitResult.forEach(System.out::println);

System.out.print("\n");

// sorted

List<Interge> sortedNumbers = Arrays.asList(11, 2, 2, 6, 4, 3, 9);

List<Interge> sortedResult = sortedNumbers.stream().sorted((a, b) -> a < b ? 1 : a == b ? 0 : -1).collect(Collectors.toList());

sortedResult.forEach(System.out::println);

System.out.print("\n");

// parallel

List<String> parallelNumbers = Arrays.asList("a", "d", "a", "b", "c","d", "e", "f");

List<String> parallelResult = parallelNumbers.parallelStream().filter(str -> str.equals("a")).collect(Collectors.toList());

parallelResult.forEach(System.out::println);

System.out.print("\n");

// Collectors

List<String> collectorsStr = Arrays.asList("a", "d", "a", "b", "c","d", "e", "f"); // 返回List

List<String> collectorResultList = collectorsStr.stream()

.filter(str -> !str.isEmpty()).collect(Collectors.toList());

System.out.println("列表: " + collectorResultList);

// 返回String

String collectorResultString = collectorsStr.parallelStream()

.filter(str -> !str.isEmpty()).collect(Collectors.joining("+"));

System.out.println("合并: " + collectorResultString);

}

}

能力有限,先寫到這,部分要點(diǎn)來自網(wǎng)絡(luò),僅作學(xué)習(xí)之用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我的筆記 關(guān)于Chromium 源文章地址 源代碼語言 結(jié)構(gòu) Chromium分為三個(gè)主要部分(不包括其他庫):瀏...
    zhchhhemmm閱讀 168評(píng)論 0 1
  • 說實(shí)話今天的心情不咋滴。。。 在一些項(xiàng)目中大家都會(huì)遇到讓獲取你現(xiàn)在的地理位置呀,或者拿到位置去上傳服務(wù)器給你提供天...
    嗯_(tái)新閱讀 732評(píng)論 3 5
  • https://developer.android.com/studio/test/index.html http...
    不排版閱讀 259評(píng)論 0 0
  • React-native-animatable 動(dòng)畫 react-native-carousel 輪播 react...
    suyuja閱讀 165評(píng)論 0 0
  • ~inverted_laser (string, default: "false")(1.1.1中已移除; 改用t...
    Danny_a44d閱讀 2,019評(píng)論 0 0

友情鏈接更多精彩內(nèi)容