今天小編給大家分享一下java stream如何使用的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
成都創(chuàng)新互聯(lián)服務(wù)項目包括連城網(wǎng)站建設(shè)、連城網(wǎng)站制作、連城網(wǎng)頁制作以及連城網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,連城網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到連城省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
我喜歡用google的集合工具類,讓我構(gòu)造測試數(shù)據(jù)更簡便。然后也用lombok,依賴:
<!--google集合工具類--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.0-jre</version> </dependency> <!--lombok,需要插件配合使用--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency>
User類
/* *鏈?zhǔn)秸{(diào)用,我也有寫相關(guān)博客,不過不是介紹基礎(chǔ)用法的,是這個鏈?zhǔn)秸{(diào)用一個不太完美的地方, *感興趣的可以去看一看:https://blog.csdn.net/ql_7256/article/details/120274432 */ @Data @Accessors(chain = true) public class User { private String username; private String password; private Integer age; private Integer height; private Address address; private Map others; }
Address類,注意:這個類在后續(xù)的測試中要改動
@Data @Accessors(chain = true) public class Address { private String province; private String city; private String county; }
數(shù)據(jù)準(zhǔn)備,
private List<User> users = new ArrayList<User>() {{ add(new User().setUsername("張三").setPassword("123456").setAge(20).setHeight(170) .setAddress(new Address().setProvince("四川省").setCity("成都市").setCounty("武侯區(qū)")) .setOthers(ImmutableMap.builder().put("sorted","AAA").put("bbb","BBB").put("ccc","CCC").build())); add(new User().setUsername("李四").setPassword("123456").setAge(16).setHeight(175) .setAddress(new Address().setProvince("四川省").setCity("成都市").setCounty("錦江區(qū)")) .setOthers(ImmutableMap.builder().put("sorted","DDD").put("eee","EEE").put("fff","FFF").build())); add(new User().setUsername("王五").setPassword("123456").setAge(20).setHeight(180) .setAddress(new Address().setProvince("四川省").setCity("成都市").setCounty("青羊區(qū)")) .setOthers(ImmutableMap.builder().put("sorted","GGG").put("hhh","HHH").put("iii","III").build())); add(new User().setUsername("趙六").setPassword("123456").setAge(17).setHeight(168) .setAddress(new Address().setProvince("四川省").setCity("成都市").setCounty("高新區(qū)")) .setOthers(ImmutableMap.builder().put("sorted","JJJ").put("kkk","KKK").put("lll","LLL").build())); }}; private List<String> strings = new ArrayList<String>() {{ add("222");add("666");add("444");add("111");add("333");add("555"); }}; private List<Integer> integers = new ArrayList<Integer>() {{ add(222);add(555);add(666);;add(333);add(444);add(111); }}; private List others = new ArrayList() {{ add(444);add(555);add(666);add(111);add(222);add(333); }};
stream流、方法引用、lambda那些前置知識咱們就不說了哈,直接上手,先體直觀的驗一下排序
List<String> sortedStrings = strings.stream().sorted().collect(Collectors.toList()); // [111, 222, 333, 444, 555, 666] System.out.println(sortedStrings); List<User> sortedUsers = users.stream().sorted(Comparator.comparing(e -> e.getAge())).collect(Collectors.toList()); // 等效寫法如下 // List<User> sortedUsers = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList()); // [User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III})] System.out.println(sortedUsers);
很簡單,也沒啥難理解的,就是排序
排序的初體驗之后,我們來看看幾種正式場景下的使用
在上面的體驗排序中,排序的結(jié)果默認(rèn)都是升序的,那如果我要降序呢?那怎么辦?有三種方式,或者三種寫法
根據(jù)user中的age降序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList()); // [User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF})] System.out.println(collect);
根據(jù)User中age先排序,默認(rèn)情況下是升序,然后再逆序一下,就變成了降序。但是這樣有點不好,因為是先排序然后在逆序的,要兩步操作。
根據(jù)user中的age降序
List<User> collect1 = users.stream().sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder())).collect(Collectors.toList()); // [User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF})] System.out.println(collect1);
這種方式原理和和方法1差不多,只是寫法不一樣
方式1和方式2都是利用sorted默認(rèn)序,然后再逆序來實現(xiàn)排序的,這樣會有兩個步驟,先升序,然后再逆序。難道就沒有直接按照降序來排序的方法?肯定是有的。既然是排序,肯定是可以指定規(guī)則的
按照年齡降序
List<User> collect2 = users.stream().sorted((x, y) -> y.getAge().compareTo(x.getAge())).collect(Collectors.toList()); // [User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF})] System.out.println(collect2);
這種方式是通過Integer中的compareTo方法來實現(xiàn)降序的,當(dāng)然也可以自己實現(xiàn),只不過age是Integer類型,既然Integer中已經(jīng)實現(xiàn)兩個Integer比較的方法,就可以偷個懶
List<User> collect3 = users.stream().sorted((x, y) -> y.getAge() - x.getAge()).collect(Collectors.toList()); // [User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF})] System.out.println(collect3);
比較實際的最終結(jié)果就是返回一個數(shù)字,大于0、小于0、等于0,分別就代表大于、小于、等于,所以在sorted方法中返回一個做減法的數(shù)字即可。
比如我現(xiàn)在的需求是先按照年齡降序,年齡相同的再按照名字降序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge, Comparator.reverseOrder()).thenComparing(User::getHeight, Comparator.reverseOrder())).collect(Collectors.toList()); // [User(username=王五, password=123456, age=20, height=180, address=Address(province=四川省, city=成都市, county=青羊區(qū)), others={sorted=GGG, hhh=HHH, iii=III}), User(username=張三, password=123456, age=20, height=170, address=Address(province=四川省, city=成都市, county=武侯區(qū)), others={sorted=AAA, bbb=BBB, ccc=CCC}), User(username=趙六, password=123456, age=17, height=168, address=Address(province=四川省, city=成都市, county=高新區(qū)), others={sorted=JJJ, kkk=KKK, lll=LLL}), User(username=李四, password=123456, age=16, height=175, address=Address(province=四川省, city=成都市, county=錦江區(qū)), others={sorted=DDD, eee=EEE, fff=FFF})] System.out.println(collect);
thenComparing顧名思義,再比較
放在以前,我肯定會從stream 排序的api說起,看看有哪些方法,再看怎么調(diào)用,但是這流式太過抽象,所以我先講了怎么用,再回頭來看看有哪些api,本質(zhì)是什么
在java.util.stream.Stream中,sorted方法有兩個重載形式
一個是無參,一個是需要一個參數(shù)java.util.Comparator。
其實這兩個方法我們都用過,在初體驗中,第一個就是無參的,這樣會根據(jù)默認(rèn)規(guī)則排序,至于默認(rèn)規(guī)則是什么,就是排序?qū)ο髮崿F(xiàn)的java.lang.Comparable接口中的compareTo方法,不然你試試跑一下這個
List<User> collect = users.stream().sorted().collect(Collectors.toList());
直接報錯,報錯的原因就是,你要排序一堆User,但是sorted這個無參的方法不知道排序的規(guī)則是什么。所以,在使用這個無參的方法時,被排序的元素必須得實現(xiàn)java.lang.Comparable接口,來指定排序規(guī)則。
除了初體驗中的第一個排序,其他的全都是使用的這個方法,很神奇是吧?我好像傳的參數(shù)不止這樣。
但事實上就是這樣子,只傳了這個一個參數(shù),無非有兩種傳參形式:一種是確確實實的傳了一個java.util.Comparator進(jìn)去,另外一種是自己實現(xiàn)了java.util.Comparator中的抽象方法compare,這個方法用來進(jìn)行元素間的比較。因為java.util.Comparator是一個函數(shù)式接口,接口中只有compare這一個抽象方法,所以可以結(jié)合lambda表達(dá)式使用。
我們使用的.sorted(Comparator.comparing(……))其實就是直接傳了一個Comparator進(jìn)去,因為Comparator.comparing這個方法:java.util.Comparator#comparing(java.util.function.Function<? super T,? extends U>, java.util.Comparator<? super U>) 返回的就是一個Comparator。
而類似這種使用:sorted((x, y) -> y.getAge().compareTo(x.getAge()))或者sorted((x, y) -> y.getAge() - x.getAge()),其實就是我們自己在實現(xiàn)java.util.Comparator中的抽象方法compare,這其實就是匿名內(nèi)部類---->簡化---->lambda表達(dá)式的這么一個過程,其實還可以簡化成 方法引用。
以上就是“java stream如何使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章題目:javastream如何使用
本文地址:http://chinadenli.net/article24/gehjje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、Google、企業(yè)網(wǎng)站制作、商城網(wǎng)站、用戶體驗、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)