由于粉絲大多數(shù)是小白本篇文章會啰嗦一些,敬請諒解畔咧!高手請忽略文章介紹直入代碼主題违诗。
一某抓、介紹
Java 8 API添加了一個新的抽象層流Stream,它以一種聲明的方式處理數(shù)據(jù)惰瓜,最后由最終操做獲得前面處理的結(jié)果否副。
Stream專一于集合對象的操做,將要處理的元素集合看做一種流崎坊, 流在管道中傳輸备禀, 而且能夠在管道的節(jié)點上進行處理, 好比篩選奈揍, 排序曲尸,聚合等。
Stream在處理大批量數(shù)據(jù)操做中更加高效男翰。
Stream + Lambda 表達式能夠極大提升Java程序員的生產(chǎn)力另患,讓程序員寫出高效率、干凈蛾绎、簡潔的代碼昆箕。
stream的三大特性:一、不存儲數(shù)據(jù)租冠;二鹏倘、不改變源數(shù)據(jù);三肺稀、延時執(zhí)行第股。
stream優(yōu)勢:一、簡化代碼话原;二夕吻、使用并行流能夠利用多核特性,提高效率繁仁。
stream上的全部操做分為兩類:中間操做和結(jié)束操做涉馅,中間操做只是一種標記,只有結(jié)束操做才會觸發(fā)實際計算黄虱。
二稚矿、什么是流
Stream不是集合元素,它不是數(shù)據(jù)結(jié)構(gòu)并不保存數(shù)據(jù)捻浦,它是有關(guān)算法和計算的晤揣,它更像一個高級版本的Iterator。原始版本的Iterator朱灿,用戶只能顯式地一個一個遍歷元素并對其執(zhí)行某些操做昧识;高級版本的Stream,用戶只要給出須要對其包含的元素執(zhí)行什么操做盗扒,好比跪楞,“過濾掉長度大于 10 的字符串”缀去、“獲取每一個字符串的首字母”等,Stream會隱式地在內(nèi)部進行遍歷甸祭,作出相應(yīng)的數(shù)據(jù)轉(zhuǎn)換缕碎。Stream就如同一個迭代器(Iterator),單向池户,不可往復(fù)咏雌,數(shù)據(jù)只能遍歷一次,遍歷過一次后即用盡了煞檩,就比如流水從面前流過处嫌,一去不復(fù)返。
而和迭代器又不一樣的是斟湃,Stream能夠并行化操做,迭代器只能命令式地檐薯、串行化操做凝赛。顧名思義,當使用串行方式去遍歷時坛缕,每一個item讀完后再讀下一個item墓猎。而使用并行去遍歷時,數(shù)據(jù)會被分紅多個段赚楚,其中每一個段在不一樣的線程中處理毙沾,而后將結(jié)果一塊兒輸出。Stream的并行操做依賴于Java7中引入的Fork/Join框架(JSR166y)來拆分任務(wù)和加速處理過程宠页。
Stream 的另一大特色是左胞,數(shù)據(jù)源自己能夠是無限的。
工做中举户,常常會須要對集合內(nèi)的元素進行排序烤宙。利用Java8能夠很方便的對List內(nèi)的元素進行排序操做;而在不少狀況下sql很差
解決的多表查詢俭嘁,臨時表分組躺枕,排序,盡可能用java8新特性stream進行處理供填。
三拐云、如何使用
List 倒序排列
List<Double> salesData = new ArrayList<>();
Collections.reverse(salesData);
java8 stream多字段排序
List<類> rankList = new ArrayList<>(); 表明某個集合
//返回 對象集合以類屬性一升序排序
rankList.stream().sorted(Comparator.comparing(類::屬性一));
//返回 對象集合以類屬性一降序排序 注意兩種寫法
rankList.stream().sorted(Comparator.comparing(類::屬性一).reversed()); //先以屬性一升序,而后對結(jié)果集進行屬性一降序
rankList.stream().sorted(Comparator.comparing(類::屬性一, Comparator.reverseOrder())); //以屬性一降序
//返回 對象集合以類屬性一升序 屬性二升序
rankList.stream().sorted(Comparator.comparing(類::屬性一).thenComparing(類::屬性二));
//返回 對象集合以類屬性一降序 屬性二升序 注意兩種寫法
rankList.stream().sorted(Comparator.comparing(類::屬性一).reversed().thenComparing(類::屬性二));//先以屬性一升序,升序結(jié)果進行屬性一降序,再進行屬性二升序
rankList.stream().sorted(Comparator.comparing(類::屬性一,Comparator.reverseOrder()).thenComparing(類::屬性二));//先以屬性一降序,再進行屬性二升序
//返回 對象集合以類屬性一降序 屬性二降序 注意兩種寫法
rankList.stream().sorted(Comparator.comparing(類::屬性一).reversed().thenComparing(類::屬性二,Comparator.reverseOrder()));//先以屬性一升序,升序結(jié)果進行屬性一降序,再進行屬性二降序
rankList.stream().sorted(Comparator.comparing(類::屬性一,Comparator.reverseOrder()).thenComparing(類::屬性二,Comparator.reverseOrder()));//先以屬性一降序,再進行屬性二降序
//返回 對象集合以類屬性一升序 屬性二降序 注意兩種寫法
rankList.stream().sorted(Comparator.comparing(類::屬性一).reversed().thenComparing(類::屬性二).reversed());//先以屬性一升序,升序結(jié)果進行屬性一降序,再進行屬性二升序,結(jié)果進行屬性一降序?qū)傩远敌?
rankList.stream().sorted(Comparator.comparing(類::屬性一).thenComparing(類::屬性二,Comparator.reverseOrder()));//先以屬性一升序,再進行屬性二降序
- 注意兩種寫法
一、 Comparator.comparing(類::屬性一).reversed();
二近她、 Comparator.comparing(類::屬性一,Comparator.reverseOrder());
兩種排序是徹底不同的叉瘩,必定要區(qū)分開來:方式1是獲得排序結(jié)果后再排序,方式2是直接進行排序P顾健7拷摇备闲!方式2更好理解。
關(guān)于java8 的stream排序用法到此介紹完畢捅暴。接下來是采坑的地方
四恬砂、踩坑
- 關(guān)于java8 的stream排序用法上面有說,介紹在多字段排序時遇到過的一個坑蓬痒。
- 需求:須要根據(jù)id去分組泻骤,而后取出每組中行號最大的一個對象值。
想到能夠利用stream的多字段排序梧奢,先按id去排狱掂,再看行號去排,demo代碼以下:
/**
* Author : PH
* Date : 2022/4/6
* ApiNote : 實體類
*/
public class Tt {
private int id;
private int line;
public Tt(int id, int line) {
this.id = id;
this.line = line;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getLine() {
return line;
}
public void setLine(int line) {
this.line = line;
}
@Override
public String toString() {
return "Tt{" +
"id=" + id +
", line=" + line +
'}';
}
}
對象代碼如上亲轨,只提供id和行號字段趋惨,作演示用:
測試代碼以下:
public static void main(String[] args) {
List<Tt> list = new ArrayList<>();
list.add(new Tt(1,2));
list.add(new Tt(2,2));
list.add(new Tt(5,2));
list.add(new Tt(5,1));
list.add(new Tt(4,2));
list.add(new Tt(7,2));
list.add(new Tt(3,2));
List<Tt> sortedList = list.stream() .sorted(Comparator.comparing(Tt::getId)).sorted(Comparator.comparing(Tt::getLine))
.collect(Collectors.toList());
System.err.println(sortedList);
}
根據(jù)理論,應(yīng)該是先根據(jù)id去排好序惦蚊,再根據(jù)行號去排號序器虾,效果應(yīng)該是,按id順序打印的蹦锋。結(jié)果以下: 發(fā)現(xiàn)其實并非想像的效果兆沙,結(jié)果是按后者順序打印的。
由此推斷出莉掂,當須要用到stram多條件排序的時候葛圃,須要最后排序的字段須要放在前面排,改后代碼以下:
List<Tt> sortedList = list.stream() .sorted(Comparator.comparing(Tt::getLine)).sorted(Comparator.comparing(Tt::getId))
.collect(Collectors.toList());
效果以下: 達到預(yù)期憎妙,問題解決库正!
相關(guān)文章
- java8 stream多字段排序
- 嵌套List排序,java8 Stream流排序
- java8的Stream的排序
- java8的stream用于排序
- java8新特性stream流
- Java8新特性---Stream(流)
- Java8新特性——stream流
- JAVA8新特性之Stream流
- Java8新特性--流(Stream)
- java8 stream代替for循環(huán) sort多字段排序 group by多級排序
- java8 stream排序空字段排在前面或后面
- Java8 stream根據(jù)字段分組并排序
- JAVA8 Stream 映射 排序
- List使用stream單字段排序
- Java8中的Stream()與ParallelStream()的區(qū)別尚氛;
- Java集合Stream類filter的使用