Java中的排序(stream多字段排序踩坑)

由于粉絲大多數(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)文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诀诊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子阅嘶,更是在濱河造成了極大的恐慌属瓣,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讯柔,死亡現(xiàn)場離奇詭異抡蛙,居然都是意外死亡,警方通過查閱死者的電腦和手機魂迄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門粗截,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捣炬,你說我怎么就攤上這事熊昌≌篱唬” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵婿屹,是天一觀的道長灭美。 經(jīng)常有香客問我,道長昂利,這世上最難降的妖魔是什么届腐? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蜂奸,結(jié)果婚禮上犁苏,老公的妹妹穿的比我還像新娘。我一直安慰自己扩所,他們只是感情好围详,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碌奉,像睡著了一般短曾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赐劣,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音哩都,去河邊找鬼魁兼。 笑死,一個胖子當著我的面吹牛漠嵌,可吹牛的內(nèi)容都是我干的咐汞。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼儒鹿,長吁一口氣:“原來是場噩夢啊……” “哼化撕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起约炎,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤植阴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后圾浅,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掠手,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年狸捕,在試婚紗的時候發(fā)現(xiàn)自己被綠了喷鸽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡灸拍,死狀恐怖做祝,靈堂內(nèi)的尸體忽然破棺而出砾省,到底是詐尸還是另有隱情,我是刑警寧澤混槐,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布编兄,位于F島的核電站,受9級特大地震影響纵隔,放射性物質(zhì)發(fā)生泄漏翻诉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一捌刮、第九天 我趴在偏房一處隱蔽的房頂上張望碰煌。 院中可真熱鬧,春花似錦绅作、人聲如沸芦圾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽个少。三九已至,卻和暖如春眯杏,著一層夾襖步出監(jiān)牢的瞬間夜焦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工岂贩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茫经,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓萎津,卻偏偏與公主長得像卸伞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锉屈,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351