Java8:流 學會用流

目錄:
- 什麼是流
- 8個例子用上流
- 總結流
- 列表

什麼是流

  1. java.util.Stream的一個接口,簡稱流,可以處理數據更加方便。可以看成遍歷數據集的高級迭代器。
  2. 提供串行和並行兩種模式進行匯聚操作,併發模式能夠充分利用多核處理器的優勢。
  3. Stream 可以並行化操作,迭代器只能命令式地、串行化操作。
  4. Stream 的另外一大特點是,數據源本身可以是無限的。
    5.流的結構
    流的結構.png

8個例子用上流

  1. 先建立兩個bean類(可跳過不看)
class Trader{
   private  String name;
    private  String city;
...
}
class Transaction{
   private Trader trader;
    private int year;
    private int value;
...
}
  1. 建立對象
   //建立對象
        Trader xiaoming=new Trader("小明","廣州");
        Trader xiaohong=new Trader("小紅","廣州");
        Trader xiaohei=new Trader("小黑","廣州");
        Trader xiaobai=new Trader("小白","肇慶");

        //新建一個交易的集合
        List<Transaction> transactions= Arrays.asList(
                new Transaction(xiaoming,2017,300),
                new Transaction(xiaohong,2016,1000),
                new Transaction(xiaohong,2017,400),
                new Transaction(xiaohei,2016,710),
                new Transaction(xiaohei,2016,700),
                new Transaction(xiaobai,2016,950)
        );
  1. 問題一,找出2016年發生的所有交易,並按交易額從低到高排列
    • 重點:考擦篩選和排序
    • 知識點:
    • filter(Predicate):Stream :詞篩選。Predicate 就是函數式接口,可用lamdba表達式
    • sorted():Stream:自定義比較
    • collect(Collectores):終端,結束流
    • 代碼:
 list=transactions.stream()
                .filter(s->s.getYear()==2016)
                .sorted(Comparator.comparing(Transaction::getValue))
                .collect(Collectors.toList());
         System.out.println(list);
  1. 問題二 交易員都在那些不同的城市工作
    • 重點:map的作用,可以轉換類型。還有去重複
    • 知識點:
    • map(Function):Stream:接收一個函數作參數,該函數會將每一個元素傳入的值映射成另外的一個元素,按照1:1的比例。
    • distinct():Stream:會去除相同的元素,根據元素的hashCode和equals方法實現。
    • 代碼
 List<String> mylist=transactions.stream()
                .map(transaction -> transaction.getTrader().getCity())
                .distinct()
                .collect(Collectors.toList());
        System.out.println(mylist);
  1. 問題三 查找所有來自於廣州工作的交易員,並按名字排序
    • 重點:獲取關鍵詞,關鍵詞排序
    • 代碼:
       List<Trader> 廣州 = transactions.stream()
                .map(Transaction::getTrader)
                .filter(t -> t.getCity().equals("廣州"))
                .sorted(Comparator.comparing(Trader::getName))
                .distinct()
                .collect(Collectors.toList());
        System.out.println(廣州);
  1. 問題四 返回所有交易員的姓名字符串,按字母順序排序
    • 重點: reduce的作用,可以把元素組合起來
    • 知識點:reduce(BinaryOperator)Optional:這個方法的主要作用是把 Stream 元素組合起來。它提供一個起始值(種子),然後依照運算規則(BinaryOperator),和前面 Stream 的第一個、第二個、第 n 個元素組合。
    • 代碼:
String collect = transactions.stream()
                .map(t->t.getTrader().getName())
                .distinct()
                .sorted(Comparator.comparing(String::toString))
                .reduce("",(n1,n2)->n1+n2);
        System.out.println(collect);
  1. 問題五 有沒有交易員在肇慶工作,返回boolean
    • 知識點:anyMath的作用,判斷至少有一個 存在
    • 代碼
 boolean 肇慶 = transactions.stream()
                .anyMatch(t -> t.getTrader().getCity().equals("肇慶"));

        System.out.println(肇慶);
  1. 問題六 打印生活在廣州的交易員的所有交易額
    • 知識點:
    • forEach(Consumer):遍歷每一個元素
    • 代碼
transactions.stream()
                .filter(t->t.getTrader().getCity().equals("廣州"))
                .map(Transaction::getValue)
                .forEach(System.out::println);
  1. 問題七 所有交易中,最高的交易額是多少
    • 重點:reduce的運用 max
    • 代碼
Optional<Integer> reduce = transactions.stream()
                .map(Transaction::getValue)
                .reduce(Integer::max);
        System.out.println(reduce.get());

10 . 問題八 找到交易額最小的交易
- 重點:reduce的運用 min



        Optional<Integer> reduce1 = transactions.stream()
                .map(Transaction::getValue)
                .reduce(Integer::min);
        System.out.println(reduce1.get());

流的總結

流的中間部分(流處理)

篩選和切片

  • filter(Predicate):Stream :詞篩選。Predicate 就是函數式接口,可用lamdba表達式
  • distinct():Stream:會去除相同的元素,根據元素的hashCode和equals方法實現。
  • limit(int):Stream:返回一個不超過給定長度的流,用來獲取前N個值。
  • skip(int):Stream:返回一個跳掉前面N個值的流,跟limit()方法互補。
  • sorted():Stream:自定義比較

映射

  • map(Function):Stream:接收一個函數作參數,該函數會將每一個元素傳入的值映射成另外的一個元素,按照1:1的比例。
  • flatMap(Function):Stream:一對多的映射,層級結構扁平化,就是將最底層元素抽出來放到一起。

數值流

  • 映射到數值流:mapToInt,mapToDouble和mapToLong.
  • 轉換回對象流:.boxed()
  • 默認值OptionalInt:
  • 數值範圍:range()和rangeClosed(),這兩個方法都是第一個參數時接受起始值,第二個接受結束值。但range()不包含結束值。

構建流

  • 由值創建流Stream.of()
  • 由數組創建流 Arrays.stream()
  • 由文件生成流 Files.lines
  • 由函數生成流:
    • Stream.iterate():iterate 跟 reduce 操作很像,接受一個種子值,和一個 UnaryOperator(例如 f)。然後種子值成爲 Stream 的第一個元素,f(seed) 爲第二個,f(f(seed)) 第三個,以此類推。
    • Stream.generate():通過實現 Supplier 接口,你可以自己來控制流的生成。這種情形通常用於隨機數、常量的 Stream,或者需要前後元素間維持着某種狀態信息的 Stream。由於它是無限的,在管道中,必須利用 limit 之類的操作限制 Stream 大小。

終端(結束流的部分)

查找和匹配

  • anyMath(Predicate)boolean:檢查謂詞是否至少匹配一個元素
  • allMatch(Predicate)boolean:檢查謂詞是否匹配所有的元素
  • noneMatch(boolean)Predicate:確保流中沒有任何元素與給定的謂詞匹配
  • findAny()Optional:將返回當前流中的任意元素
  • findFirst()Optional:將返回第一個元素
  • forEach(Consumer):遍歷每一個元素
  • Collect:對流進行處理
    Optional簡介
    Optional類(java.util.Optional)是一個容器類,代表一個值存在或不存在。
    常用方法:
    - isPresent():將在Optional包含值的時候返回true,否則返回flase。
    - ifPresent(Consumer block):會在值存在的時候執行給定的代碼塊。
    - T get():會在值存在時返回值。
    - T orElse(T other)會在值存在時返回值。

歸約

  • reduce(BinaryOperator)Optional:這個方法的主要作用是把 Stream 元素組合起來。它提供一個起始值(種子),然後依照運算規則(BinaryOperator),和前面 Stream 的第一個、第二個、第 n 個元素組合。

列表

操作 類型 返回類型 使用的類型/函數式接口 函數描述符
filter 中間 Stream Predicate T -> boolean
distinct 中間 Stream
skip 中間 Stream long
limit 中間 Stream long
map 中間 Stream Function T -> R
flatMap 中間 Stream Function> T -> Stream
sorted 中間 Stream Comparator (T,T) -> int
anyMatch 終端 boolean Predicate T -> boolean
noneMatch 終端 boolean Predicate T -> boolean
allMatch 終端 boolean Predicate T -> boolean
findAny 終端 Optional
findFirst 終端 Optional
forEach 終端 void Consumer T -> void
collect 終端 R Collector
reduce 終端 Optional BinaryOperator (T,T) -> T
count 終端 long
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章