SQL中那麼多函數,Java8為什麼還要提供重複的Stream方法,多此一舉?

有個同學提出一個這樣的疑問;

在業務系統中,數據一般都從sql中查詢,類似使用where,order by,limit,聚合函數等,為什麼還要用java8的Stream方法?

 

對這個問題,大家有什麼見解,歡迎評論區留言

SQL中那麼多函數,Java8為什麼還要提供重複的Stream方法,多此一舉?

首先,我們可以看下Stream的方法。

stream三種創建方式

  • 集合 Collection.stream()
  • 靜態方法 Stream.of
  • 數組 Arrays.stream

Stream的終止操作

  • foreach(Consumer c) 遍歷操作
  • collect(Collector) 將流轉化為其他形式
  • max(Comparator) 返迴流中最大值
  • min(Comparator) 返迴流中最小值
  • count 返迴流中元素綜述

Collectors 具體方法

  • toList List<T> 把流中元素收集到List
  • toSet Set<T> 把流中元素收集到Set
  • toCollection Coolection<T> 把流中元素收集到Collection中
  • groupingBy Map<K,List<T>> 根據K屬性對流進行分組
  • partitioningBy Map<boolean, List<T>> 根據boolean值進行分組

Stream的中間操作

  • filter(Predicate) 篩選流中某些元素
  • map(Function f) 接收流中元素,並且將其映射成為新元素,例如從student對象中取name屬性flatMap(Function f) 將所有流中的元素併到一起連接成一個流
  • peek(Consumer c) 獲取流中元素,操作流中元素,與foreach不同的是不會截斷流,可繼續操作流
  • distinct() 通過流所生成元素的equals和hashCode去重
  • limit(long val) 截斷流,取流中前val個元素
  • sorted(Comparator) 產生一個新流,按照比較器規則排序
  • sorted() 產生一個新流,按照自然順序排序

匹配

  • booelan allMatch(Predicate) 都符合
  • boolean anyMatch(Predicate) 任一元素符合
  • boolean noneMatch(Predicate) 都不符合

以上列舉了一些Stream()常用操作方法,其實大部分在SQL中都能實現,同時類似Oracle,MySQL等數據庫,有無數大牛用了十幾年的時間幫我們做這些操作的優化處理,自帶優化到極致的索引和緩存。所以如果在數據量大的情況下,有條件使用SQL處理,理論上比Stream提供的方法要快。

Stream大部分功能重疊了SQL自帶函數方法,既然這樣,Java8為什麼還要提供這類API呢,效率你又干不過人家?

Stream有自己的使用場景,現在微服務越來越流行,一個系統被拆N多個服務,每個服務又使用不同的數據庫,但是往往不同服務之間,在數據上有交叉。這種情況下,在SQL上的處理就會變得很麻煩。

比如,現在有A服務(會員管理),存儲了會員信息,包括會員等級、登記日期、近期消費情況等。B服務(註冊用戶管理),存儲了用戶基本信息,包括住址、聯繫電話、生日等;想要總覽會員信息,VVIP會員需要在生日時候送上一條彩信祝福和一款不值錢的庫存商品作為禮物。

統計或者總覽會員信息的時候,你就沒辦法用一條SQL去搞定了,這時候,Stream的分組,過濾,匹配等函數就發揮了作用。Java8之前,這些操作可能需要用循環或者iterator來做,比較繁瑣,而Stream流可以很順暢的一口氣實現之前需要大段代碼才能實現的功能。

如:

篩選大於18歲的會員

List<VIPUsers> collect = lists.stream().filter(e -> e.getAge() > 18).collect(Collectors.toList());

根據會員類型分組

Map<String, List<VIPUsers>> collect3 = lists.stream()
        .collect(Collectors.groupingBy(vUser::getType));

統計總數

long count = lists.stream().count();

都可以很方便的操作。

Stream是Java8對集合操作的優化,相較於迭代器,使用Stream的速度非常快,並且它支持並行方式處理集合中的數據,默認情況能充分利用cpu的資源。同時支持函數式編程,代碼非常簡潔。在日常開發中使用Stream,開發效率更快,代碼更加簡潔。

但是需要注意的是,不要過分依賴Stream操作,常用的過濾聚合分組等操作,如果Stream和SQL都能處理的場景下,更建議去使用SQL去操作,尤其是數據量大的情況下,要充分利用數據庫自帶的緩存和索引,不要想着自己去優化。

老潘說過,叔怕你把握不住啊孩子,讓數據庫來!!!