一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 都9102年了,你還用for循環(huán)操作集合嗎

都9102年了,你還用for循環(huán)操作集合嗎

2021-07-20 16:29cdream Java教程

這篇文章主要給大家介紹了關(guān)于java中for循環(huán)操作集合使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

前段時間公司書架多了一本《java8 實戰(zhàn)》,畢竟久聞lambda的大名,于是借來一閱。這一看,簡直是驚為天人啊,lambda,stream,java8里簡直是滿腦子騷操作,看我的一愣一愣的。我甚至是第一次感覺到了什么叫優(yōu)雅。

都9102年了,你還用for循環(huán)操作集合嗎

本文主要介紹java8中的流處理,看看java8是怎么愉快的玩耍集合的,讓我們來一起感受java8的魅力吧!

我就隨便舉個例子,看看stream有多優(yōu)雅。

?
1
2
3
4
5
6
7
// 對蘋果按顏色匯總并績數(shù)量
map<string, long> applecount = apples.stream()
 .collect(groupingby(apple::getcolor, counting()));
// 過濾掉顏色為黑色的蘋果,并匯總好蘋果的總金額
double sum = apples.stream()
 .filter(i->"black".equals(i.getcolor()))
 .collect(tolist);

一、lambda表達式

雖然本文重點是stream,但是stream中需要傳遞lambda表達式,所以簡單介紹一下lambda表達式。lambda表達式其實就是匿名函數(shù)(anonymous function),是指一類無需定義標識符的函數(shù)或子程序。

java中匿名函數(shù)的表現(xiàn)形式,只留下入?yún)⒑头椒w中的內(nèi)容

?
1
2
3
4
5
6
// 普通函數(shù)
public void run(string s){
 system.out.print(s+"哈哈");
}
// 我不要名字啦!??!
(s)->system.out.print(s+"哈哈")

誒,過去我們都用對象調(diào)方法的,你弄這個沒名的東西啥時候用啊?

java中我們通過函數(shù)式接口來使用這種匿名函數(shù)。

函數(shù)式接口

1.java中只包含一個未實現(xiàn)方法的接口。其中可以有與object中同名的方法和默認方法(java8中接口方法可以有默認實現(xiàn))。

2.java中函數(shù)式接口使用@functionalinterface進行注解。runnable、comparator都是函數(shù)式接口。

3.java.util.function包下為我們提供很多常用的函數(shù)式接口,例如function等。

用法舉例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 實現(xiàn)runnable中的run方法,替代匿名內(nèi)部類。
runnable r = ()->system.out.print("哈哈");
// 作為參數(shù)傳遞。
new thread(()-> system.out.println("haha")).start();
 
arraylist<apple> list = new arraylist<>();
list.foreach(i-> system.out.println(i.getweight()));
 
 
// 簡化策略模式
public static list<apple> filterapples(list<apple> inventory,applepredicate p){
 list<apple> apples = new arraylist<>();
 for(apple apple : inventory){
 if(p.test(apple)){
 apples.add(apple);
 }
 }
 return apples;
}
public class bigapple implement applepredicate{
 @override
 public boolean test(apple a){
 if(a.getweight>10){
 return a
 }
 }
}
// 這是個簡單的策略模式,根據(jù)用戶的需要,創(chuàng)建不同的接口applepredicate實現(xiàn)類,調(diào)用時傳入不同的實現(xiàn)類就可以,但問題是如果需求過多,創(chuàng)建的實現(xiàn)類也會很多,過于臃腫不方便管理。
xx.filterapple(inventory,new bigapple);
// 使用lambda表達式,不在需要創(chuàng)建bigapple類
xx.filterapple(inventory,i->(i.getweight>10));

使用lambda表達式可以簡化大量的模板代碼,并且可以向方法直接傳遞代碼。

總之

方法出參入?yún)碜院瘮?shù)式接口

?
1
2
3
4
5
6
7
8
9
10
//入?yún),返回void
(s)->system.out.println(s);
//入?yún)⒖眨祷豽oid
()->system.out.print("haha");
//入?yún),返回i+1
i->i+1
//后面寫代碼塊
apple->{if(apple.getweiht>5) return "big";
 else return "small";
 }

好了,不多啰嗦了,如果感興趣推薦下面的文章或《java8實戰(zhàn)》的前三章。

1.Lambda表達式有何用處?如何使用?

2.java8實戰(zhàn)

二、stream

流是什么?

java api的新成員,它允許你使用聲明式方式處理數(shù)據(jù)集合(類似sql,通過查詢語句表達,而不是臨時編寫一個實現(xiàn))。

如果有人說lambda表達式不易于理解,那還勉強可以接受(其實過于復(fù)雜的lambda缺失不好閱讀,但通常lambda不會做太復(fù)雜的實現(xiàn)),但流真的非常的易懂易用。這個語法糖真的是甜死了。

注意事項:

1.流只能使用一次,遍歷結(jié)束就代表這個流被消耗掉了

2.流對集合的操作屬于內(nèi)部迭代,是流幫助我們操作,而不是外部迭代

3.流操作包含:數(shù)據(jù)源,中間操作鏈,終端操作三個部分。

基礎(chǔ)流操作

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
list<double> collect = list.stream()
 // 過濾掉黑色的蘋果
 .filter(i -> "black".equals(i.getcolor()))
 // 讓蘋果按照重量個價格排序
 .sorted(comparator.comparing(apple::getweight)
 .thencomparing(i->i.getprice()))
 // 篩選掉重復(fù)的數(shù)據(jù)
 .distinct()
 // 只要蘋果的價格
 .map(apple::getprice)
 // 只留下前兩條數(shù)據(jù)
 .limit(2)
 // 以集合的形式返回
 .collect(tolist());
// 循環(huán)打印列表中元素
list.foreach(i->system.out.print(i));

apple::getprince<=>i -> i.getprince()可以看做是僅涉及單一方法的語法糖,效果與lambda表達式相同,但可讀性更好。

同理

下面列表為常見操作

中間

 

操作 類型 作用 函數(shù)描述 函數(shù)
filter 中間 過濾 t -> boolean predicate
sorted 中間 排序 (t,t)->int comparator
map 中間 映射 t->r function<t,r>
limit 中間 截斷    
distinct 中間 去重,根據(jù)equals方法    
skip 中間 跳過前n個元素    

 

終端

 

操作 類型 作用
foreach 終端 消費流中的每個元素,使用lambda進行操作
count 終端 返回元素個數(shù),long
collect 終端 將流歸約成一個集合,如list,map甚至是integer

 

篩選與切片

?
1
2
3
4
5
6
7
8
9
10
list<string> strings = arrays.aslist("hello", "world");
list<string> collect1 = strings.stream()
 // string映射成string[]
 .map(i -> i.split(""))
 // arrays::stream 數(shù)據(jù)數(shù)組,返回一個流string[]->stream<string>
 // flatmap各數(shù)組并不分別映射成一個流,而是映射成流的內(nèi)容 stream<string>->stream
 .flatmap(arrays::stream)
 .collect(tolist());
system.out.println(collect);
----->輸出 [h, e, l, l, o, w, o, r, l, d]

歸約操作reduce

?
1
2
3
4
5
6
7
8
9
10
11
12
list<integer> integers = arrays.aslist(12, 3, 45, 3, 2,-1);
// 有初始值的疊加操作
integer reduce = integers.stream().reduce(3, (i, j) -> i + j);
integer reduce2 = integers.stream().reduce(5, (x, y) -> x < y ? x : y);
// 無初始值的疊加操作
optional<integer> reduce1 = integers.stream().reduce((i, j) -> i + j);
// 無初始值的最大值
optional<integer> reduce4 = integers.stream().reduce(integer::min);
// 無初始值的最大值
optional<integer> reduce5 = integers.stream().reduce(integer::max);
// 求和
optional<integer> reduce6 = integers.stream().reduce(integer::sum);

reduce做的事情是取兩個數(shù)進行操作,結(jié)果返回取下一個數(shù)操作,以次類推。

optional是java8引入的新類,避免造成空指針異常,在集合為空時,結(jié)果會包在optional中,可以用ispresent()方法來判斷是否為空值。

無初始值的情況下可能為空,故返回optional

中間

 

操作 類型 作用 函數(shù)描述 函數(shù)
flatmap 中間 使通過的流返回內(nèi)容 t -> boolean predicate

 

終端

 

操作 類型 作用
anymatch 終端 返回boolean,判斷是否有符合條件內(nèi)容
nonematch 終端 返回boolean,判斷是否無符合條件內(nèi)容
allmatch 終端 返回boolean,判斷是全為符合條件內(nèi)容
findany 終端 optional,隨機找一個元素返回
findfirst 終端 optional,返回第一個元素
reduce 終端 optional (t,t)->t 歸約操作

 

數(shù)值流

包裝類型的各種操作都會有拆箱操作和裝箱操作,嚴重影響性能。所以java8為我們提供了原始數(shù)值流。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 數(shù)值流求平均值
optionaldouble average = apples.stream()
 .maptodouble(apple::getprice)
 .average();
// 數(shù)值流求和
optionaldouble average = apples.stream()
 .maptodouble(apple::getprice)
 .sum();
// 數(shù)值流求最大值,沒有則返回2
double v = apples.stream()
 .maptodouble(apple::getprice)
 .max().orelse(2);
// 生成隨機數(shù)
intstream s = intstream.rangeclosed(1,100);

下面列表為常見數(shù)值流操作操作

中間

 

操作 類型 作用
rangeclosed(1,100) 中間 生成隨機數(shù)(1,100]
range(1,100) 中間 生成隨機數(shù)(1,100)
boxed() 中間 包裝成一般流
maptoobj 中間 返回為對象流
maptoint 中間 映射為數(shù)值流

 

終端,終端操作與list一般流類似

構(gòu)建流

值創(chuàng)建

?
1
stream<string> s = stream.of("java","python");

數(shù)組創(chuàng)建

?
1
2
int[] i = {2,3,4,5};
stream<int> = arrays.stream(i);

由文件生成,nio api已經(jīng)更新,以便利用stream api

?
1
stream<string> s = files.lines(paths.get("data.txt"),charset.defaultcharset());

由函數(shù)創(chuàng)建流:無限流

?
1
2
3
4
5
6
7
8
// 迭代
stream.iterate(0,n->n+2)
 .limit(10)
 .foreach(system.out::println);
// 生成,需要傳遞實現(xiàn)supplier<t>類型的lambda提供的新值
stream.generate(math.random)
 .limit(5)
 .foreach(system.out::println);

三、總結(jié)

至此,本文講述了常見的流操作,目前排序、篩選、求和、歸約等大多數(shù)操作我們都能實現(xiàn)了。與過去相比,操作集合變的簡單多了,代碼也變的更加簡練明了。

目前vert.x,spring新出的webflux都通過lambda表達式來簡化代碼,不久的將來,非阻塞式框架的大行其道時,lambda表達式必將變的更加重要!

至于開篇見到的分組!??!下篇文章見~

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.cnblogs.com/cdream-zs/p/10504499.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产馆| 欧美图片另类小说综合 | 大色综合 | 大胸被c出奶水嗷嗷叫 | 欧美日韩在线观看一区二区 | 无限好资源免费观看 | 大胸被c出奶水嗷嗷叫 | 美女模特被c免费视频 | 西西人体大胆77777视频 | 免费永久视频 | 亚洲国产天堂久久综合网站 | 久久伊人中文字幕有码 | 99精品国产综合久久久久 | 美女又爽又黄免费 | 色多多视频在线 | 欧美ay| 四虎免费影院在线播放 | 免费在线观看中文字幕 | 欧美高清片 | japanesemoms乱熟| 成人免费观看www视频 | 女暴露狂校园裸露小说 | 日本中文字幕高清 | 91久久碰国产 | 国产成人综合精品一区 | 亚洲国产精品高清在线 | 日本不卡不码高清免费观看 | 性福演算法 | 1769最新资源站 | 2014天堂 | 国产精品久久久久久 | 人人人人人看碰人人免费 | 色噜噜视频影院 | 欧美黑人ⅹxxx片 | 日本一在线中文字幕天堂 | 亚洲不卡视频在线观看 | 91青青国产在线观看免费 | 青青国产成人久久激情91麻豆 | 久久精品无码人妻无码AV蜜臀 | 九九精品视频在线播放 | 美女脱了内裤打开腿让人羞羞软件 |