java8簡單入門

1、介紹

  本片文章會從一下幾個知識點進行介紹:

  • 函數式接口 @FunctionalInterface
  • Lambda 表達式
  • 函數引用 Function Reference
  • Stream

  看了幾篇關于 java8 入門的例子,其中引入了許多令人期待已久的特性(雖然我沒有過這樣的體會),但不管你的代碼是普通青年款還是文藝青年款,你都可以從被 java8 的重新組織的代碼看到她的簡潔之處,不得不讓我對這些新入貴圈(java圈)的小鮮肉做一些記錄,以便我能很好的利用他們。

  最大的一個特點莫非就是引入了“函數式”編程這一個概念(都是剽竊的別的語言來的),還有那么多新奇的詞語,比如“語法糖”“閉包”“顯式|隱式函數”等這里我就不再一個一個去體會了,這里屬于初次接觸,先理解會用為主,細節的深入待后期慢慢琢磨。

?

2、函數式接口 -- @Functionnalinterface

  在翠花正式上代碼示例之前,我們現來對這個函數式接口有個認識:

  1. 接口必須只有一個抽象方法;
  2. 接口可以有其他的默認(default)或者靜態(static)方法;
  3. 接口默認繼承了 Object 類,所以接口中不能覆蓋了 Object 中的方法;

說明:該注解不是必須的,如果一個接口滿足“函數式接口”特性,那么不加這個注解也沒有影響,加上該注解能夠更好的讓編譯器檢查,如果不符合規范將會報編譯錯誤。

  比如在 jdk8 中就對Comparator、Callable、Runnable等接口加上了該注解,下面兩段代碼的效果是一樣的:

  

 1 public static void runThreadByLambda() {
 2     Runnable runnable = () -> System.out.println("這個是用拉姆達實現的線程");
 3     new Thread(runnable).start();
 4 }
 5 
 6 //---------------------------------------------------------------------------------
 7 public static void runThreadByInnerClass() {
 8     Runnable runnable = new Runnable() {
 9     @Override
10     public void run() {
11         System.out.println("這個是用內部類實現的線程");
12     }
13     };
14     new Thread(runnable).start();
15 }

?3、Lambda 表達式

  先用自己的語言來個 Lambda 下個定義:"一段帶有輸入參數的可執行語句塊”。精確與否那是別人的事情,反正我是這么理解的(目前階段是這樣的)。

1 (Type1 param1, Type2 param2, ..., TypeN paramN) -> {
2   statment1;
3   statment2;
4   //.............
5   return statmentM;
6 }

  對應定義我們自然要給個例子

1 List<String> names = new ArrayList<>();
2 names.add("TaoBao");
3 names.add("ZhiFuBao");
4 List<String> lowercaseNames = names.stream().map((String name) -> {return name.toLowerCase();}).collect(Collectors.toList());

  這不就是將一個集合全部元素變為小寫嗎?和我以前用的循環代碼繁簡度不想上下,有什么好奇怪的!這位看管不要著急嘛,下面我來個他搓個背您再看看如何。

1 List<String> lowercaseNames = names.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());
2 
3 //如果加入方法應用就是這樣
4 List<String> lowercaseNames = names.stream().map(String::toLowerCase()).collect(Collectors.toList());

  簡化規則如下:

  • 絕大部分情況下,編譯器都可以從上下文推算出參數類型,因此可以省略
  • 當參數只有一個,可以省略小括號
  • 當表達式只包含一條語句時,可以省略大括號、returned和語句結尾的分號

  在 Lambda 眼中,外部的變量也是可以訪問的,只是這個變量默認必須是 final ,即便你自己沒有加上,編譯器也會自動幫你加上,所以變大時內部訪問外部變量必須是不可變的(只是引用不可變);還有一個東西就是 this ,this 在 lambda 指代的不是表達式生產的那個 SAM(Simple Abstract Method)對象,而是申明她的外部對象。

?

4、方法引用(Method reference)和構造器引用(Construct reference)

  • objectName::instanceMethod ?
  • ClassName::staticMethod
    例子:System.out::println ? 等同于 ? x -> System.out.println(x)
    ?????????? Math::max ? ? ? ? ? ? ? ?等同于 ?(x,y) -> Math.max(x,y)
    前兩種方法類似,等同于把 Lambda 表達式的參數當成實例方法或者靜態方法的參數來調用,下面再來看看第三種情況
  • ClassName::instanceMethod
    例子:String.toLowerCase ??等同于 ? x -> x.toLowerCase()
    等同于把 Lambda 表達式的第一個參數當成 實例方法的目標對象,其余參數當成該方法的參數來調用。
  • ClassName::new
    例子:BigDecimal::new ? ?等同于 ? x -> new BigDecimal(x)
    等同于把 Lambda 的參數當成構造器的參數來調用。

5、Stream

  Stream 堪稱 Lambda 的好基友,他們兩個配合起來使用才能快快樂樂。

  • Stream 是元素的集合,這點讓 Stream 看起來有些類似 iterator

  • 可以支持順序和并行的對原 Stream 進行匯聚的操作
//Lists是Guava中的一個工具類
List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);

?

?

?

?

?

  5.1 創建 Stream

// of() 有兩個,變長參數和單一參數
Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
Stream<String> stringStream = Stream.of("taobao");
// 匿名類的寫法
Stream.generate(new Supplier<Double>() {@Overridepublic Double get() {return Math.random();}
});
// Lambda 寫法
Stream.generate(() -> Math.random);
// 函數引用寫法
Stream.generate(Math::random);
// generate() 生產一個無限長度的Stream
// iterate() 也是生產了一個無限長度的 Stream ,其是重復調用用戶給定的種子值類獲取元素,seed  f(seed)  f(f(seed))  ......
Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);

    除了上面 Stream 的靜態工廠創建方法之外,就是下面的 Collection 接口的默認方法。

1 public interface Collection<E> extends Iterable<E> {
2     //其他方法省略
3     default Stream<E> stream() {
4         return StreamSupport.stream(spliterator(), false);
5     }
6 }

  5.2? 轉換 Stream

    顧名思義,就是通過一定的法則將原來的 Stream 轉換成一個新的 Stream,下面列舉一些常用的轉換方法來加深理解,一圖勝千言

?

?

?

從以上圖中就可以看出來幾個常用的 轉換函數的功能,下面我們將大聲的喊出我們的口號“在一起!”

1 List<Integer> nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
2 System.out.println(“sum is:”+nums.stream().filter(num -> num != null).
3                distinct().mapToInt(num -> num * 2).
4                peek(System.out::println).skip(2).limit(4).sum());

  5.3 匯聚(Reduce) Stream

    匯聚,也稱為折疊,接受一個元素序列為輸入,反復使用某個合并操作,把序列中的元素合并成一個匯總的結果,下面會分兩部分來介紹匯聚行為。

    5.3.1 可變匯聚

      把輸入元素累計到一個可變的容器中,比如 Collection 或者 StringBuilder。

    5.3.2 其他匯聚

      除了可變匯聚之外的其余匯聚,一般不是通過反復修改某個可變對象,而是通過把前一次的匯聚結果當成下一次的入參,反復如此,比如reduce、count、allMatch

?    

?

轉載于:https://www.cnblogs.com/afanti558/p/7181867.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252318.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252318.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252318.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

玩轉帶外觸發的單目相機之一

背景&#xff1a;去年開始研究vins,但是只是用了普通的相機&#xff0c;然后將IMU和相機粘在一起&#xff0c;然后就是聯合標定相機和IMU。VINS使用的相機是帶有外觸發的&#xff0c;還進行了相機和IMU的硬件時間同步。當時我特別想買個帶外觸發的相機&#xff0c;一直沒找到資…

基于django的視頻點播網站開發-step11-后臺用戶管理功能...

用戶管理功能&#xff0c;包含用戶添加、列表展示、編輯、刪除四大功能。下面我們一一揭曉。 用戶添加 我們先實現用戶添加功能&#xff0c;我們現在urls.py下添加相關的路由 path(user_add/, views.UserAddView.as_view(), nameuser_add), path(user_list/, views.UserListVie…

BZOJ 1070 拆點 費用流

1070: [SCOI2007]修車 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 5860 Solved: 2487[Submit][Status][Discuss]Description 同一時刻有N位車主帶著他們的愛車來到了汽車維修中心。維修中心共有M位技術人員&#xff0c;不同的技術人員對不同 的車進行維修所用的時間是不…

分布式之數據庫和緩存雙寫一致性方案解析

先做一個說明&#xff0c;從理論上來說&#xff0c;給緩存設置過期時間&#xff0c;是保證最終一致性的解決方案。這種方案下&#xff0c;我們可以對存入緩存的數據設置過期時間&#xff0c;所有的寫操作以數據庫為準&#xff0c;對緩存操作只是盡最大努力即可。也就是說如果數…

使用python從csv文件中讀入兩列擬合直線

背景&#xff1a;要判斷跟蹤算法在控制目標物走直線的情況下跟蹤的軌跡是否為直線&#xff0c;我保存下來跟蹤算法跟蹤到的目標的中心點在圖像上的像素位置&#xff0c;然后擬合出穿過這些點的直線&#xff0c;然后計算這些點距離直線的平均距離來判斷跟蹤的精度。&#xff08;…

window document

1 打開一個新窗口 var newDocwindow.open("text/html","replace");var txt"<html><body>Learning about the DOM is FUN!</body></html>";newDoc.document.write(txt);newDoc.close(); //該方法將關閉 open() 方法打開…

‘(‘:illegal token on right side of ‘::‘

背景&#xff1a;想整理升級一下代碼&#xff0c;添加了兩個類&#xff0c;再一編譯代碼&#xff0c;出現了好多這樣的錯誤提示“(:illegal token on right side of ::”&#xff0c;我很納悶這是啥問題&#xff0c;我就使用“注釋法”來定位出錯的位置&#xff0c;我發現把所有…

mysql-數據庫操作

doc界面操作mysql:<br/> 以phpstudy為例 登錄數據庫&#xff1a;進入phpstudy/mysql/bin下&#xff0c;mysql -u用戶名 -p密碼 選擇數據庫&#xff1a;use 數據庫名; 設置編碼格式&#xff1a;set names gbk; 查看表結構或字段信息&#xff1a;desc 表名; 建立數據庫&…

虹軟免費人臉識別SDK注冊指南

2019獨角獸企業重金招聘Python工程師標準>>> 成為開發者三步完成賬號的基本注冊與認證&#xff1a; STEP1:點擊注冊虹軟AI開放平臺右上角注冊選項&#xff0c;完成注冊流程。 STEP2:首次使用&#xff0c;登錄后進入開發者中心&#xff0c;點擊賬號管理完成企業或者個…

Mybatis使用statementType=STATEMENT實現動態傳入表名或字段名

mybatis中使用statementType"STATEMENT"實現動態傳入字段名時一直報語句錯誤&#xff0c;但實際上語句并沒有毛病&#xff0c;爬了一天坑才找到問題&#xff0c;記錄一下。 整條語句中里所有傳入的值都要使用${xxx},不能使用#{xxx}。 <select id"listMap&quo…

C++中的類加多線程代碼修煉

背景&#xff1a;現在在做一個目標跟蹤的項目&#xff0c;需要實時的從工業相機中獲取圖像&#xff0c;然后再跟蹤圖像上的目標物&#xff0c;由于起初為了測試跟蹤算法&#xff0c;就把“從相機獲取圖像”和“跟蹤處理”都放在了主線程中&#xff0c;在實際測試時&#xff0c;…

Activity Monitor 閃退 無法進入睡眠

Activity Monitor 閃退 & 無法進入睡眠 情況描述 黑蘋果?主機突然無法進入睡眠。 考慮到可能是后臺程序阻礙了系統正常進入睡眠&#xff0c; 于是想要通過Activity Monitor查看系統的活動情況&#xff0c;然而&#xff0c;Activity Monitor閃退。 重新開機&#xff0c;快速…

hbase中清空整張表的數據

hbase(main):005:0> truncate fr:test Truncating FaceBase table (it may take a while):- Disabling table...- Dropping table...- Creating table...0 row(s) in 14.4220 seconds truncate是disable、drop、create三個動作的自動化集成。轉載于:https://www.cnblogs.com…

hibernate樹

1. 樹實現通過pid進行指向上一層來實現&#xff0c;實體類代碼如下 package com.test.model;import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.per…

Sleep() sleep() usleep()

Linux: sleep(n); //停留n秒 usleep(n); //停留n微秒 Windows: Sleep(n); //停留n毫秒

vue的鼠標移入和移出

vue的鼠標移入和移出 需求&#xff08;鼠標到預約二維碼顯示&#xff0c;預約添加背景色&#xff09; 實現 <!--html部分--> <ul class"person_list"> //五個li標簽皆是循環渲染出來的<li class"item" v-for"(n,index) in 5">…

聊聊flink的MemoryPool

為什么80%的碼農都做不了架構師&#xff1f;>>> 序 本文主要研究一下flink的MemoryPool MemoryPool flink-runtime_2.11-1.7.2-sources.jar!/org/apache/flink/runtime/memory/MemoryManager.java abstract static class MemoryPool {abstract int getNumberOfAvai…

day4

ti很簡單&#xff0c;但是把變量弄錯了&#xff0c;寫了不到半小時&#xff0c;調了一小時&#xff0c;導致t3功虧一簣。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> …

C++中public protected private的區別

1. 不考慮繼承關系時 本類方法使用外部使用private是否protected是否public是是 2. 有繼承關系時 子類方法使用外部private否否protected是否public是是 結論&#xff1a;基于以上兩個表格可以知道&#xff0c;C中的protected處于private和public中間&#xff0c; protected 既…

表達式求值

表達式求值問題 ①問題描述 表達式是數據運算的基本形式。人們的書寫習慣是中綴式&#xff0c;如&#xff1a;1122*(7-4)/3。中綴式的計算按運算符的優先級及括號優先的原則&#xff0c;相同級別從左到右進行計算。表達式還有后綴式&#xff08;如&#xff1a;22 7 4 - * 3 / 1…