您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Java8中Stream API如何終止”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Java8中Stream API如何終止”這篇文章吧。
我們都知道Stream API完成的操作是需要三步的:創(chuàng)建Stream → 中間操作 → 終止操作。那么這篇文章就來說一下終止操作。
終端操作會(huì)從流的流水線生成結(jié)果。其結(jié)果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
首先,我們?nèi)匀恍枰粋€(gè)自定義的Employee類,以及一個(gè)存儲它的List集合。
在Employee類定義了枚舉(BUSY:忙碌;FREE:空閑;VOCATION:休假)
package com.szh.java8; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * */ @Data @NoArgsConstructor @AllArgsConstructor public class Employee2 { private Integer id; private String name; private Integer age; private Double salary; private Status status; public Employee2(Integer id) { this.id = id; } public Employee2(Integer id, String name) { this.id = id; this.name = name; } public enum Status { FREE, BUSY, VOCATION } }
List<Employee2> employees = Arrays.asList( new Employee2(1001,"張三",26,6666.66, Employee2.Status.BUSY), new Employee2(1002,"李四",50,1111.11,Employee2.Status.FREE), new Employee2(1003,"王五",18,9999.99,Employee2.Status.VOCATION), new Employee2(1004,"趙六",35,8888.88,Employee2.Status.BUSY), new Employee2(1005,"田七一",44,3333.33,Employee2.Status.FREE), new Employee2(1005,"田七二",44,3333.33,Employee2.Status.VOCATION), new Employee2(1005,"田七七",44,3333.33,Employee2.Status.BUSY) );
查找所有的員工是否都處于BUSY狀態(tài)、至少有一個(gè)員工處于FREE狀態(tài)、沒有員工處于VOCATION狀態(tài)。
@Test public void test1() { boolean b1 = employees.stream() .allMatch((e) -> e.getStatus().equals(Employee2.Status.BUSY)); System.out.println(b1); boolean b2 = employees.stream() .anyMatch((e) -> e.getStatus().equals(Employee2.Status.FREE)); System.out.println(b2); boolean b3 = employees.stream() .noneMatch((e) -> e.getStatus().equals(Employee2.Status.VOCATION)); System.out.println(b3); }
對員工薪資進(jìn)行排序之后,返回第一個(gè)員工的信息; 篩選出BUSY狀態(tài)員工之后,返回任意一個(gè)處于BUSY狀態(tài)的員工信息。
@Test public void test2() { Optional<Employee2> op1 = employees.stream() .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())) .findFirst(); System.out.println(op1.get()); System.out.println("----------------------------------"); Optional<Employee2> op2 = employees.stream() .filter((e) -> e.getStatus().equals(Employee2.Status.BUSY)) .findAny(); System.out.println(op2.get()); }
下面,我們來看一下另外一組查找與匹配的方法。
計(jì)算處于VOCATION狀態(tài)的員工數(shù)量;對員工薪資字段進(jìn)行映射,同時(shí)獲取其中的最高薪資;獲取年齡最小的員工信息。
@Test public void test3() { long count = employees.stream() .filter((e) -> e.getStatus().equals(Employee2.Status.VOCATION)) .count(); System.out.println(count); Optional<Double> op1 = employees.stream() .map(Employee2::getSalary) .max(Double::compare); System.out.println(op1.get()); Optional<Employee2> op2 = employees.stream() .min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())); System.out.println(op2.get()); }
在這里,大家需要注意的一點(diǎn)就是:當(dāng)前Stream流一旦進(jìn)行了終止操作,就不能再次使用了。
我們看下面的代碼案例。(異常信息說的是:stream流已經(jīng)被關(guān)閉了)
@Test public void test4() { Stream<Employee2> stream = employees.stream() .filter((e) -> e.getStatus().equals(Employee2.Status.BUSY)); long count = stream.count(); stream.map(Employee2::getName); }
Collector 接口中方法的實(shí)現(xiàn)決定了如何對流執(zhí)行收集操作 (如收集到 List、Set、Map) 。但是 Collectors 實(shí)用類提供了很多靜態(tài)方法,可以方便地創(chuàng)建常見收集器實(shí)例,具體方法與實(shí)例如下表:
計(jì)算整數(shù)1~10的和;對員工薪資字段進(jìn)行映射,之后獲取所有員工的薪資總和。
@Test public void test1() { List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer sum = list.stream() .reduce(0, (x, y) -> x + y); System.out.println(sum); System.out.println("-------------------------------"); Optional<Double> optional = employees.stream() .map(Employee2::getSalary) .reduce(Double::sum); System.out.println(optional.get()); }
依次對我們先前定義好的存儲員工信息的List集合 做name字段的映射,然后 轉(zhuǎn)為 List、Set、HashSet(使用 Collectors 實(shí)用類中的靜態(tài)方法即可完成)。
在Set、HashSet集合中,由于元素是無序、不可重復(fù)的,所以只有一個(gè)田七二。
@Test public void test2() { List<String> list = employees.stream() .map(Employee2::getName) .collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("-------------------------------"); Set<String> set = employees.stream() .map(Employee2::getName) .collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("-------------------------------"); HashSet<String> hashSet = employees.stream() .map(Employee2::getName) .collect(Collectors.toCollection(HashSet::new)); hashSet.forEach(System.out::println); }
對員工薪資字段做映射,之后通過比較器獲取最高薪資;
不做映射處理,直接通過比較器獲取薪資最低的員工信息;
計(jì)算所有員工的薪資總和;
計(jì)算所有員工的平均薪資;
計(jì)算員工總數(shù);
對員工薪資字段做映射,之后通過比較器獲取最高薪資;
@Test public void test3() { Optional<Double> max = employees.stream() .map(Employee2::getSalary) .collect(Collectors.maxBy(Double::compare)); System.out.println(max.get()); Optional<Employee2> min = employees.stream() .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))); System.out.println(min.get()); Double sum = employees.stream() .collect(Collectors.summingDouble(Employee2::getSalary)); System.out.println(sum); Double avg = employees.stream() .collect(Collectors.averagingDouble(Employee2::getSalary)); System.out.println(avg); Long count = employees.stream() .collect(Collectors.counting()); System.out.println(count); DoubleSummaryStatistics dss = employees.stream() .collect(Collectors.summarizingDouble(Employee2::getSalary)); System.out.println(dss.getMax()); }
單個(gè)條件分組:根據(jù)員工狀態(tài)對Stream流進(jìn)行分組。 因?yàn)榉纸M之后得到的是一個(gè)Map集合,key就是員工狀態(tài),value則是一個(gè)List集合。
@Test public void test4() { Map<Employee2.Status, List<Employee2>> map = employees.stream() .collect(Collectors.groupingBy(Employee2::getStatus)); Set<Map.Entry<Employee2.Status, List<Employee2>>> set = map.entrySet(); Iterator<Map.Entry<Employee2.Status, List<Employee2>>> iterator = set.iterator(); while (iterator.hasNext()) { Map.Entry<Employee2.Status, List<Employee2>> entry = iterator.next(); System.out.println(entry.getKey()); System.out.println(entry.getValue()); } }
多個(gè)條件分組:先按照員工狀態(tài)分組,如果狀態(tài)相同,再按照員工年齡分組。
@Test public void test5() { Map<Employee2.Status, Map<String, List<Employee2>>> map = employees.stream() .collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e) -> { if (e.getAge() <= 35) { return "成年"; } else if (e.getAge() <= 60) { return "中年"; } else { return "老年"; } }))); Set<Employee2.Status> set = map.keySet(); Iterator<Employee2.Status> iterator = set.iterator(); while (iterator.hasNext()) { Employee2.Status next = iterator.next(); Map<String, List<Employee2>> listMap = map.get(next); System.out.println(next); System.out.println(listMap); } }
根據(jù)特定的條件對員工進(jìn)行分區(qū)處理。(員工薪資大于等于5000為 true 分區(qū);否則都為 false 分區(qū))。
@Test public void test6() { Map<Boolean, List<Employee2>> map = employees.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000)); map.forEach((key,value) -> System.out.println("鍵:" + key + ", 值:" + value)); }
以上是“Java8中Stream API如何終止”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。