【Java必修課】圖說Stream中的skip()和limit()方法及組合使用

1 簡介

本文將講解Java 8 Stream中的兩個方法:skip()limit()。這兩個方法是Stream很常用的,不僅各自會被高頻使用,還可以組合出現,並能實現一些小功能,如subList和分頁等。

2 skip()方法

見名知義,skip()方法用於跳過前面n個元素,然後再返回新的流,如圖所示:

file

來看看代碼:

List<Integer> result = Stream.of(1, 2, 3, 4, 5, 6)
  .skip(4)
  .collect(Collectors.toList());
List<Integer> expected = asList(5, 6);
assertEquals(expected, result);

方法skip()的參數n的四種情況:

(1)當n<0時,拋IllegalArgumentException異常;

(2)當n=0時,相當沒有跳過任何元素,原封不動、完璧歸趙;

(3)當0時,跳過n個元素後,返回含有剩下的元素的流;

(4)當n>=length時,跳過所有元素,返回空流。

3 limit()方法

對於limit()方法,它是用於限制流中元素的個數,即取前n個元素,返回新的流,如圖所示:

file

代碼如下:

List<Integer> result = Stream.of(1, 2, 3, 4, 5, 6)
  .limit(4)
  .collect(Collectors.toList());
List<Integer> expected = asList(1, 2, 3, 4);
assertEquals(expected, result);

方法limit()的參數n的四種情況:

(1)當n<0時,拋IllegalArgumentException異常;

(2)當n=0時,不取元素,返回空流;

(3)當0時,取前n個元素,返回新的流;

(4)當n>=length時,取所有元素,原封不動、完璧歸趙。

4 對無限流的操作

流Stream分爲有限流和無限流,前面的例子我們都是使用的有限流,與Java集合類不同,流是可以無限的。對於無限流,skip()limit()表現出了極大的差異,先上代碼:

Stream.iterate(1, i -> i   1)
  .filter(num -> (num & (num - 1)) == 0)
  .limit(10)
  .forEach(System.out::println);
System.out.println("----------------");
Stream.iterate(1, i -> i   1)
  .filter(num -> (num & (num - 1)) == 0)
  .skip(10)
  .forEach(System.out::println);

執行後發現,limit()是可以將無限流轉化爲有限流的,所以我們也可以認爲它是一個短路操作。而skip()則不行,不管你跳過了前面多少個元素,總還是會有源源不斷的元素過來,無法收斂。

上述代碼的結果是:

通過limit()輸出了前十個2的n次方值:1, 2, 4, 8, 16, 32, 64, 128, 256, 512

skip()而跳過了前10個,繼續輸出,但會不斷執行下去(會有int的溢出現象):

1024, 2048, 4096, 8192, 16384, 32768...

5 組合應用

除了兩者各自有各自的功能外,我們通過組合使用,可以實現其它功能。

5.1 與subList的替換

集合類如List是有subList()這個方法的,可以截取List中的某一部分,這個功能還可以通過組合skip()limit()使用得到,如下面代碼:

List<Integer> list = asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<Integer> expected = list.subList(3, 7);

List<Integer> result = list.stream()
  .skip(3)
  .limit(7 - 3)
  .collect(Collectors.toList());
assertEquals(expected, result);

subList(startIndex, endIndex)轉換成skip(startIndex).limit(endIndex - startIndex)

5.2 分頁

可以通過組合使用skip()limit()進行分頁,如下面代碼:

int pageSize = 10;
int pageIndex = 7;

List<Integer> expected = asList(61, 62, 63, 64, 65, 66, 67, 68, 69, 70);
List<Integer> result = Stream.iterate(1, i -> i   1)
  .skip((pageIndex - 1) * pageSize)
  .limit(pageSize)
  .collect(Collectors.toList());

assertEquals(expected, result);

上面代碼例子是獲取了第七頁數據,每頁大小爲10。

6 總結

本文介紹了Java 8的Stream接口中兩個常用的方法:skip()limit(),比較簡單易懂,也介紹了怎麼組合使用。需要注意的是,如果Stream過大或是無限流,小心skip()會有性能問題。

歡迎關注公衆號<南瓜慢說>,將持續爲你更新...

file

歡迎加博主微信,做一個點贊之友,哈哈...

file

多讀書,多分享;多寫作,多整理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章