成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

樂字節(jié)-Java8新特性之Stream流(下)

20171112 / 3420人閱讀

摘要:歸約操作計(jì)算有效訂單總金額有效訂單總金額收集數(shù)據(jù)收集將流轉(zhuǎn)換為其他形式,方法作為終端操作,接收一個(gè)接口的實(shí)現(xiàn),用于給中元素做匯總的方法。

接上一篇:《Java8新特性之stream》,下面繼續(xù)接著講Stream

5、流的中間操作

常見的流的中間操作,歸為以下三大類:篩選和切片流操作、元素映射操作、元素排序操作:

5.1、篩選和切片

例如以訂單數(shù)據(jù)為例,在做報(bào)表展示時(shí),會(huì)根據(jù)訂單狀態(tài)、用戶信息、支付結(jié)果等狀態(tài)來分別展示(即過濾和統(tǒng)計(jì)展示)

定義訂單Order類

public class Order {
    // 訂單id
    private Integer id;
    // 訂單用戶id
    private Integer userId;
    // 訂單編號
    private  String orderNo;
    // 訂單日期
    private Date orderDate;
    // 收貨地址
    private String address;
    // 創(chuàng)建時(shí)間
    private Date createDate;
    // 更新時(shí)間
    private Date updateDate;
    // 訂單狀態(tài)  0-未支付  1-已支付  2-代發(fā)貨  3-已發(fā)貨  4-已接收  5-已完成
    private Integer status;
    // 是否有效  1-有效訂單  0-無效訂單
    private Integer isValid;
    
    //訂單總金額
    private  Double total;
    /**
       此處省略getter/setter方法
    */
}

測試

public static void main(String[] args) {
        Order order01 = new Order(1,10,"20190301",
                new Date(),"上海市-浦東區(qū)",new Date(),new Date(),4,1,100.0);
        Order order02 = new Order(2,30,"20190302",
                new Date(),"北京市四惠區(qū)",new Date(),new Date(),1,1,2000.0);
        Order order03 = new Order(3,20,"20190303",
                new Date(),"北京市-朝陽區(qū)",new Date(),new Date(),4,1,500.0);
        Order order04 = new Order(4,40,"20190304",
                new Date(),"北京市-大興區(qū)",new Date(),new Date(),4,0,256.0);
        Order order05 = new Order(5,40,"20190304",
                new Date(),"上海市-松江區(qū)",new Date(),new Date(),4,0,1000.0);
        List ordersList= Arrays.asList(order01,order02,order03,order04);
        // 過濾訂單集合 有效訂單 并打印到控制臺(tái)
        ordersList.stream().filter((order)->order.getIsValid()==1).forEach(System.out::println);
        // 過濾訂單集合有效訂單 取前兩條有效訂單 并打印到控制臺(tái)
        ordersList.stream().filter((order)->order.getIsValid()==1).limit(2).forEach(System.out::println);
    }
         // 過濾訂單集合有效訂單 取最后一條記錄
        ordersList.stream().filter((order)->order.getIsValid()==1)
                .skip(ordersList.size()-2).forEach(System.out::println);

// 去除訂單編號重復(fù)的無效訂單記錄 此時(shí)因?yàn)楸容^的為Object Order對象需要重寫HashCode 與Equals 方法
/**
     * 重寫 equals 方法
     * @param obj
     * @return
     */
    @Override
    public boolean equals(Object obj) {
        boolean flag = false;
        if (obj == null) {
            return flag;
        }
        Order order = (Order) obj;
        if (this == order) {
            return true;
        } else {
            return (this.orderNo.equals(order.orderNo));
        }
    }

    /**
     * 重寫hashcode方法
     * @return
     */
    @Override
    public int hashCode() {
        int hashno = 7;
        hashno = 13 * hashno + (orderNo == null ? 0 : orderNo.hashCode());
        return hashno;
    }
 // 過濾訂單集合無效訂單 去除訂單號重復(fù)記錄
  ordersList.stream().filter((order)->order.getIsValid()==0).distinct().forEach(System.out::println);
5.2、映射
//過濾訂單集合有效訂單  獲取所有訂單訂單編號
ordersList.stream().filter((order)->order.getIsValid()==1).map((order)->order.getOrderNo()).forEach(System.out::println);

// 過濾有效訂單  并分離每個(gè)訂單下收貨地址市區(qū)信息
ordersList.stream().map(o->o.getAddress().split("-")).flatMap(Arrays::stream).forEach(System.out::println);
5.3、排序
 //過濾有效訂單 并根據(jù)用戶id 進(jìn)行排序
 ordersList.stream().filter((order)->order.getIsValid()==1)
 .sorted((o1,o2)->o1.getUserId()-o2.getUserId()).forEach(System.out::println);
//或者等價(jià)寫法
ordersList.stream().filter((order)->order.getIsValid()==1)
                .sorted(Comparator.comparingInt(Order::getUserId)).forEach(System.out::println);

// 定制排序規(guī)則
/*過濾有效訂單
 * 定制排序:如果訂單狀態(tài)相同 根據(jù)訂單創(chuàng)建時(shí)間排序 反之根據(jù)訂單狀態(tài)排序
*/
ordersList.stream().filter((order)->order.getIsValid()==1).sorted((o1,o2)->{
   if(o1.getStatus().equals(o2.getStatus())){
        return o1.getCreateDate().compareTo(o2.getCreateDate());
    }else{
        return o1.getStatus().compareTo(o2.getStatus());
    }}).forEach(System.out::println);

6、流的終止操作

終止操作會(huì)從流的流水線生成結(jié)果。其結(jié)果是任何不是流的值,比如常見的List、 Integer,甚 至void等結(jié)果。

對于流的終止操作,分為以下三類:

6.1、查找與匹配
  // 篩選所有有效訂單  匹配用戶id =20 的所有訂單
System.out.println("allMatch匹配結(jié)果:"+ordersList.stream().
                   filter((order) -> order.getIsValid() == 1).allMatch((o) -> o.getUserId() == 20));
System.out.println("anyMatch匹配結(jié)果:"+ordersList.stream().
                   filter((order) -> order.getIsValid() == 1).anyMatch((o) -> o.getUserId() == 20));
System.out.println("noneMatch匹配結(jié)果:"+ordersList.stream().
                   filter((order) -> order.getIsValid() == 1).noneMatch((o) -> o.getUserId() == 20));

//  篩選所有有效訂單 返回訂單總數(shù)
System.out.println("count結(jié)果:"+ordersList.stream().
                   filter((order) -> order.getIsValid() == 1).count());
// 篩選所有有效訂單 返回金額最大訂單值
Optional max=ordersList.stream().filter((order) -> order.getIsValid() == 1)
    .map(Order::getTotal).max(Double::compare);
System.out.println("訂單金額最大值:"+max.get());
// 篩選所有有效訂單 返回金額最小訂單值
Optional min=ordersList.stream().filter((order) -> order.getIsValid() == 1)
    .map(Order::getTotal).min(Double::compare);
System.out.println("訂單金額最小值:"+min.get());

6.2、歸約
將流中元素反復(fù)結(jié)合起來,得到一個(gè)值的操作。

// 歸約操作  計(jì)算有效訂單總金額
System.out.println("有效訂單總金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1).map(Order::getTotal).reduce(Double::sum).get());

6.3、Collector收集數(shù)據(jù)

6.3.1、收集

將流轉(zhuǎn)換為其他形式,coollect 方法作為終端操作, 接收一個(gè)Collector接口的實(shí)現(xiàn),用于給Stream中元素做匯總的方法。最常用的方法,把流中所有元素收集到一個(gè) List, Set 或 Collection 中

toList

toSet

toCollection

toMap

// 收集操作
// 篩選所有有效訂單 并收集訂單列表
List orders= ordersList.stream().filter((order) -> order.getIsValid() == 1).collect(Collectors.toList());
orders.forEach(System.out::println);
// 篩選所有有效訂單 并收集訂單號 與 訂單金額
Map map=ordersList.stream().filter((order) -> order.getIsValid() == 1).

collect(Collectors.toMap(Order::getOrderNo, Order::getTotal));

// java8 下對map 進(jìn)行遍歷操作 如果 Map 的 Key 重復(fù)了,會(huì)報(bào)錯(cuò)
map.forEach((k,v)->{

System.out.println("k:"+k+":v:"+v);

});

6.3.2、匯總

countintg():用于計(jì)算總和

count():用于計(jì)算總和(推薦使用,寫法更簡潔)

summingInt() ,summingLong(),summingDouble():用于計(jì)算總和

averagingInt(),averagingLong(),averagingDouble()用于平均

summarizingInt,summarizingLong,summarizingDouble 同樣可以實(shí)現(xiàn)計(jì)算總和,平均等操作,比如summarizingInt 結(jié)果會(huì)返回IntSummaryStatistics 類型 ,然后通過get方法獲取對應(yīng)匯總值即可

// 匯總操作
//篩選所有有效訂單 返回訂單總數(shù)
System.out.println("count結(jié)果:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).collect(Collectors.counting()));

System.out.println("count結(jié)果:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).count());

// 返回訂單總金額
System.out.println("訂單總金額:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).collect(Collectors.summarizingDouble(Order::getTotal)));

System.out.println("訂單總金額:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).mapToDouble(Order::getTotal).sum());

System.out.println("訂單總金額:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).map(Order::getTotal).reduce(Double::sum).get());

// 返回 用戶id=20 有效訂單平均每筆消息金額
System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+ordersList.stream().

               filter((order) -> order.getIsValid() == 1).
               filter((order -> order.getUserId()==20))
               .collect(Collectors.averagingDouble(Order::getTotal)));

System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+

               ordersList.stream().
               filter((order) -> order.getIsValid() == 1).
               filter((order -> order.getUserId()==20))
               .mapToDouble(Order::getTotal).average().getAsDouble());

System.out.println("用戶id=20 有效訂單平均每筆消費(fèi)金額:"+

               ordersList.stream().
               filter((order) -> order.getIsValid() == 1).
               filter((order -> order.getUserId()==20))
               .collect(Collectors.summarizingDouble(Order::getTotal)).getAverage());

// 篩選所有有效訂單 并計(jì)算訂單總金額
System.out.println("訂單總金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1)

               .collect(Collectors.summingDouble(Order::getTotal)));

// 篩選所有有效訂單 并計(jì)算最小訂單金額
System.out.println("最小訂單金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1)

               .map(Order::getTotal).collect(Collectors.minBy(Double::compare)));

// 篩選所有有效訂單 并計(jì)算最大訂單金額
System.out.println("最大訂單金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1)

               .map(Order::getTotal).collect(Collectors.maxBy(Double::compare)));

6.3.3、最值

maxBy,minBy 兩個(gè)方法,需要一個(gè) Comparator 接口作為參數(shù),實(shí)現(xiàn)最大 最小值獲取操作

// 取最會(huì)
// 篩選所有有效訂單 并計(jì)算最小訂單金額
System.out.println("最小訂單金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1)
                   .map(Order::getTotal).collect(Collectors.minBy(Double::compare)));
// 篩選所有有效訂單 并計(jì)算最大訂單金額
System.out.println("最大訂單金額:"+ordersList.stream().filter((order) -> order.getIsValid() == 1)
                   .map(Order::getTotal).collect(Collectors.maxBy(Double::compare)));

6.3.4、分組

groupingBy 用于將數(shù)據(jù)分組,最終返回一個(gè) Map 類型

groupingBy 可以接受一個(gè)第二參數(shù)實(shí)現(xiàn)多級分組

// 分組-根據(jù)有效訂單支付狀態(tài)進(jìn)行分組操作
Map> g01=ordersList.stream().filter((order) -> order.getIsValid() == 1)
    .collect(Collectors.groupingBy(Order::getStatus));
g01.forEach((status,order)->{
    System.out.println("----------------");
    System.out.println("訂單狀態(tài):"+status);
    order.forEach(System.out::println);
});

// 分組-查詢有效訂單 根據(jù)用戶id 和 支付狀態(tài)進(jìn)行分組
Map>> g02= ordersList.stream().filter((order) -> order.getIsValid() == 1)
    .collect(Collectors.groupingBy(Order::getUserId,Collectors.groupingBy((o)->{
        if(o.getStatus()==0){
            return "未支付";
        }else if (o.getStatus()==1){
            return "已支付";
        }else if (o.getStatus()==2){
            return "待發(fā)貨";
        }else if (o.getStatus()==3){
            return "已發(fā)貨";
        }else if (o.getStatus()==4){
            return "已接收";
        } else{
            return "已完成";
        }
    })));
g02.forEach((userId,m)->{
    System.out.println("用戶id:"+userId+"-->有效訂單如下:");
    m.forEach((status,os)->{
        System.out.println("狀態(tài):"+status+"---訂單列表如下:");
        os.forEach(System.out::println);
    });
    System.out.println("-----------------------");
});

6.3.5、partitioningBy 分區(qū)

分區(qū)與分組的區(qū)別在于,分區(qū)是按照 true 和 false 來分的,因此partitioningBy 接受的參數(shù)的 lambda 也是?T -> boolean 

// 分區(qū)操作  篩選訂單金額>1000 的有效訂單
Map> g03= ordersList.stream().filter((order) -> order.getIsValid() == 1)
    .collect(Collectors.partitioningBy((o)->o.getTotal()>1000));
g03.forEach((b,os)->{
    System.out.println("分區(qū)結(jié)果:"+b+"--列表結(jié)果:");
    os.forEach(System.out::println);
});

// 拼接操作 篩選有效訂單 并進(jìn)行拼接
String orderStr=ordersList.stream().filter((order) -> order.getIsValid() == 1).map(Order::getOrderNo)
    .collect(Collectors.joining(","));
System.out.println(orderStr);

樂字節(jié)-Java新特性之stream流就介紹到這里了,接下來小樂還會(huì)接著給大家講解Java8新特性之Optional,歡迎關(guān)注,轉(zhuǎn)載請說明出處和作者。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/77518.html

相關(guān)文章

  • 字節(jié)-Java8特性Stream(上)

    摘要:需要注意的是很多流操作本身就會(huì)返回一個(gè)流,所以多個(gè)操作可以直接連接起來,如下圖這樣,操作可以進(jìn)行鏈?zhǔn)秸{(diào)用,并且并行流還可以實(shí)現(xiàn)數(shù)據(jù)流并行處理操作。為集合創(chuàng)建并行流。 上一篇文章,小樂給大家介紹了《Java8新特性之方法引用》,下面接下來小樂將會(huì)給大家介紹Java8新特性之Stream,稱之為流,本篇文章為上半部分。 1、什么是流? Java Se中對于流的操作有輸入輸出IO流,而Jav...

    dingda 評論0 收藏0
  • 字節(jié)-Java8核心特性實(shí)戰(zhàn)Stream

    摘要:大家好,我是樂字節(jié)的小樂。需要注意的是很多流操作本身就會(huì)返回一個(gè)流,所以多個(gè)操作可以直接連接起來,如下圖這樣,操作可以進(jìn)行鏈?zhǔn)秸{(diào)用,并且并行流還可以實(shí)現(xiàn)數(shù)據(jù)流并行處理操作。為集合創(chuàng)建并行流。 大家好,我是樂字節(jié)的小樂。說起流,我們會(huì)聯(lián)想到手機(jī)、電腦組裝流水線,物流倉庫商品包裝流水線等等,如果把手機(jī) ,電腦,包裹看做最終結(jié)果的話,那么加工商品前的各種零部件就可以看做數(shù)據(jù)源,而中間一系列的...

    wenshi11019 評論0 收藏0
  • 字節(jié)-Java8核心特性實(shí)戰(zhàn)-接口默認(rèn)方法

    摘要:語法中接口可以包含實(shí)現(xiàn)方法,需要使用修飾,此類方法稱為默認(rèn)方法。核心特性接口默認(rèn)方法就介紹到這里了,后續(xù)小樂會(huì)繼續(xù)講述核心特性。 JAVA8已經(jīng)發(fā)布很久,是自java5(2004年發(fā)布)之后Oracle發(fā)布的最重要的一個(gè)版本。其中包括語言、編譯器、庫、工具和JVM等諸多方面的新特性,對于國內(nèi)外互聯(lián)網(wǎng)公司來說,Java8是以后技術(shù)開發(fā)的趨勢。這里主要講解在開發(fā)中幾個(gè)核心的新特性。(主要從...

    lbool 評論0 收藏0
  • 字節(jié)-Java8核心特性實(shí)戰(zhàn)函數(shù)式接口

    摘要:大家好,上一篇小樂給大家講述了樂字節(jié)核心特性表達(dá)式,點(diǎn)擊回顧。接下來繼續(xù)核心特性之函數(shù)式接口。感謝大家欣賞小樂帶來的核心特性之函數(shù)式接口,接下來還會(huì)更多核心技術(shù)講解,請關(guān)注樂字節(jié)如需要視頻課程,請搜索樂字節(jié)騰訊課堂 大家好,上一篇小樂給大家講述了《樂字節(jié)-Java8核心特性-Lambda表達(dá)式》,點(diǎn)擊回顧。接下來繼續(xù):Java8核心特性之函數(shù)式接口。 什么時(shí)候可以使用Lambda?通常...

    niceforbear 評論0 收藏0
  • 字節(jié)Java8核心特性Optional

    摘要:大家好啊,上次小樂給大家介紹了最最重要的一個(gè)特性流,點(diǎn)擊可以回顧哦。并且可以避免空指針異常。這種操作對于參數(shù)判斷提供很大便利,例如參數(shù)滿足指定條件的后續(xù)操作查詢操作字符串拼接,常見的處理多請求頁面轉(zhuǎn)發(fā)處理等操作。 大家好啊,上次小樂給大家介紹了Java8最最重要的一個(gè)特性——Stream流,點(diǎn)擊可以回顧哦。 Optional類(java.util.Optional)是一個(gè)容器類,代表一...

    姘存按 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<