Java Stream 流的使用

1. 篩選和切片

用謂詞篩選

filter方法接受一個返回boolean的方法。api

List<Dish> vegetarianMenu=menu.stream().filter(Dish::isVegetarian) .collect(toList());

distinct去重

distinct方法,根據流中元素的hashCode和equals方法。例:數組

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); 
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

截短流

limit(n)方法,該方法會返回一個不超過給定長度的函數

若是流是有序的,則最多會返回前n個元素。工具

limit也能夠用在無序流上,好比源是一個Set。這種狀況下,limit的結果不會以任何順序排列。code

List<Dish> dishes = menu.stream() .filter(d -> d.getCalories() > 300).limit(3).collect(toList());

跳過元素

skip(n)方法返回一個扔掉了前n個元素的流。若是流中元素不足n個,則返回一個空流。skip方法和limit方法能夠當作是相反的操做。對象

2. 映射

簡單映射

流支持map方法,它會接受一個函數做爲參數。這個函數會被應用到每一個元素上,並將其映射成一個新的元素。ip

下面的代碼,對words中的全部字符串應用String::length方法。字符串

List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action"); 
List<Integer> wordLengths = words.stream().map(String::length).collect(toList());

流的扁平化

什麼叫扁平化?舉個例子:把Stream<Stream< String >> 變成 Steam< String > 就叫扁平化。get

一言以蔽之,flatmap方法讓你把一個流中的每一個值都換成另外一個流,而後把全部的流鏈接起來成爲一個流。

List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action");
        //map函數中每一個字符串都被切割爲字符串數組,返回一個字符串數組的流
        List<String[]> collect = words.stream()
                .map(word -> word.split(""))
                .distinct()
                .collect(toList());
        //Arrays.stram方法接受一個數組返回一個流
        String[] arrayOfWords = {"Goodbye", "World"};
        Stream<String> streamOfwords = Arrays.stream(arrayOfWords);

        //第一個map返回一個字符串流,流中的元素是一個個的字符串數組。
        //第二個map對每個字符數組應用Arrays.stream函數,因此每個字         //符串數組映射爲一個字符串流。
        List<Stream<String>> collect1 = words.stream()
                .map(word -> word.split(""))
                .map(v -> Arrays.stream(v))
                .distinct()
                .collect(toList());
        //第一個map返回一個字符串流,流中的元素是一個個的字符串數組。
        //flatMap方法把流中的每一個字符串數組都換成一個流,而後鏈接它們成        //爲一個流
        List<String> uniqueCharacters =
                words.stream()
                        .map(w -> w.split(""))
                        .flatMap(Arrays::stream)
                        .distinct()
                        .collect(Collectors.toList());

3. 查找和匹配

另外一個常見的數據處理套路是看看數據集中的某些元素是否匹配一個給定的屬性。Stream API經過allMatch、anyMatch、noneMatch、findFirst、findAny方法提供了這樣的工具。

注:這些工具方法的返回值都不是流。因此它們是終端操做

檢查謂詞是否至少匹配一個元素

if(menu.stream().anyMatch(Dish::isVegetarian)){ 
 System.out.println("The menu is (somewhat) vegetarian friendly!!"); 
}

檢查謂詞是否匹配全部元素

//是否全部元素都匹配
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);
//是否全部元素都 不 匹配
boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);

查找元素

findAny方法將返回當前流中的任意元素。

Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();

Optional是什麼?

查找第一個元素

List<Integer> someNumbers = Arrays.asList(1, 2, 3, 2, 5); 
//filter返回一個流,findfirst在該流中找第一個
Optional<Integer> firstSquareDivisibleByThree = 
 someNumbers.stream() 
 .filter(x -> x == 2) 
 .findFirst();

4. 歸約

歸約:將流中的元素相互結合起來,求一個值。好比學生是元素求分數最高的學生、分數是元素求某位同窗的總分。

//求numbers中全部數值的集合
int product = numbers.stream().reduce(1, (a, b) -> a * b);
  • 一個初始值,這裏是0;

  • 一個BinaryOperator 來將兩個元素結合起來產生一個新值,這裏咱們用的是

lambda (a, b) -> a + b。

無初始值

reduce還有一個重載的變體,它不接受初始值,可是會返回一個Optional對象:

Optional sum = numbers.stream().reduce((a, b) -> (a + b));

小結

該篇對於流的使用,作了簡要的筆記。能夠知足大多數狀況的需求。不要只是看看,不要只是作了筆記。這麼好用的api,趕忙用起來吧。

相關文章
相關標籤/搜索