【JAVA基礎】Stream的操作流程

爲什麼需要使用Stream

Stream 的操作流程

  • 獲取一個數據源(source)
  • 中間數據操作
    執行中間操作,每次轉換原有 Stream 對象不改變,返回一個新的 Stream 對象(可以有多次轉換),這就允許對其操作可以像鏈條一樣排列,變成一個管道
  • 終止操作,獲得想要的結果
    如下圖所示:

Intermediate(中間數據操作):
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

Terminal(終止操作):
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

Short-circuiting(短路操作):
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny

獲取一個數據源(source)

  • Collection 和數組Arrays中的靜態方法
    Collection.stream();Collection.parallelStream()
    Arrays.stream(T array) or Stream.of()
    例如:
	Stream<String> listStream = Arrays.asList("aa","bb","cc").stream();
	String[] stringArray = {"aa","bb","cc"};
	Stream<String> arrayStream = Arrays.stream(stringArray);
  • 通過Stream類中的一些靜態方法獲取流
    例如 Stream.of();Stream.iterate();Stream.generate()
	Stream<String> stream = Stream.of("aa","bb","cc");
    Stream<Integer> stream1 = Stream.iterate(2, (x) -> x * 2);
    Stream<Double> stream2 = Stream.generate(() -> Math.random());
  • 其它一些類,可以獲取stream對象
	java.nio.file.Files.walk()
	Random.ints()
	BitSet.stream()
	Pattern.splitAsStream(java.lang.CharSequence)
	JarFile.stream()
	ava.io.BufferedReader.lines()

中間數據操作

即對數據的流進行一些需要的操作,在終止操作執行之前,中間操作可以不斷執行。
如圖:

中間操作主要用到strem類提供的一些可以返回Stream流的靜態方法,主要示例一些常用的方法,其他可參考在線中文JDK1.8 http://www.matools.com/api/java8

filter(Predicate<? super T> predicate)

顧名思義,過濾輸入流中的一些元素,只輸出符合條件的一些元素,需要給定篩選條件(Predicate<? super T> predicate)
舉例說明:

	 Stream<String> listStream = Arrays.asList("aa","bb","cc").stream();
     Stream<String> handledStream = listStream.filter(a -> "aa".equals(a));
     System.err.println("filter after:" + handledStream.collect(Collectors.toList()));

輸出結果爲:
在這裏插入圖片描述
從結果中可以看出來,原有數組中[“aa”,“bb”,“cc”],經過過濾條件 “aa”.equals(a) 的篩選以後,新輸出的數組,只剩下了符合條件的[“aa”]。
此處可能會產生兩個疑問:

  1. 此時如果執行System.err.println("before:" + listStream.collect(Collectors.toList()));會報錯,爲什麼呢?
    流只能被讀一遍,詳細見後文
  2. handledStream.collect(Collectors.toList())是什麼意思呢?
    將流轉換爲List,方便輸出查看結果,詳細見後文

按照上面的思路,把Stream中的一些靜態方法都執行一遍,看每個靜態方法都有什麼作用。

distinct()

返回由該流的不同元素(根據 Object.equals(Object) )組成的流。即去重的意思

  @Test
  public void streamDistinctTest() {
    Stream<String> listStream = Arrays.asList("aa","aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.distinct();
    System.err.println("distinct after:" + handledStream.collect(Collectors.toList()));
  }

結果如下:
在這裏插入圖片描述
從結果中看,原數組爲[“aa”,“aa”, “bb”, “cc”, “eee”, “cc”],distinct之後,重複的"aa","cc"被去除掉了。
上文中的 “根據 Object.equals(Object)” 又是什麼意思呢,即如果傳入是一個Object對象,判斷是否重複的辦法是調用equels方法去重,如果需要實現自己的去重規則,需要重寫對象中的equels方法。

limit(long maxSize)

返回由此流的元素組成的流,截短長度不能超過 maxSize。即截取maxSize長度的數據。

  @Test
  public void streamLimitTest() {
    Stream<String> listStream = Arrays.asList("aa","aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.limit(3);
    System.err.println("limit after:" + handledStream.collect(Collectors.toList()));
  }

結果如下:
在這裏插入圖片描述

skip(long n)

丟棄前n個元素,只保留後面的元素

  @Test
  public void streamSkipTest() {
    Stream<String> listStream = Arrays.asList("aa", "bb", "cc", "eee", "cc").stream();
    Stream<String> handledStream = listStream.skip(2);
    System.err.println("skip after:" + handledStream.collect(Collectors.toList()));
  }

結果如下:
在這裏插入圖片描述
從結果中可以看出來,skip跳過了前兩個元素,只返回了後三個元素

sorted()

返回由此流的元素組成的流,根據自然順序排序。

  @Test
  public void streamSortTest() {
    Stream<String> listStream = Arrays.asList("hh", "gg", "ee", "dd", "cc").stream();
    Stream<String> handledStream = listStream.sorted();
    System.err.println("sorted after:" + handledStream.collect(Collectors.toList()));
  }

結果如下:
在這裏插入圖片描述
從結果中可以看到,對原數組[“hh”, “gg”, “ee”, “dd”, “cc”],進行了一個字符串的排序

map

map()方法爲流中的每個輸入值生成一個輸出值。
因此,如果流中有n個元素,則map()操作將生成n個輸出元素的流。

  @Test
  public void streamMapTest() {
    List<String> listOfStrings = Arrays.asList("1", "2", "3", "4", "5");

    List<Integer> listOfIntegers = listOfStrings.stream()
                                    .map(Integer::valueOf)
                                    .collect(Collectors.toList());

    System.err.println(listOfIntegers);
  }

在這裏插入圖片描述

flatMap

flatMap()是兩步過程,即map()+ Flattening。
它有助於將Collection <Collection >轉換爲Collection 。

  @Test
  public void streamFlatMapTest() {
    List<Integer> list1 = Arrays.asList(1,2,3);
    List<Integer> list2 = Arrays.asList(4,5,6);
    List<Integer> list3 = Arrays.asList(7,8,9);
     
    List<List<Integer>> listOfLists = Arrays.asList(list1, list2, list3);
     
    List<Integer> listOfAllIntegers = listOfLists.stream()
                                .flatMap(x -> x.stream())
                                .collect(Collectors.toList());
     
    System.err.println(listOfAllIntegers);
  }

在這裏插入圖片描述

終止操作

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator、collect

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