Java8中建立Stream 流的四種方式以及 Stream 中間操做

Stream api

**Stream api 是java8 中提供的對集合處理的api , 對數據進行一系列的中間操做,元數據不會發生改變
                集合講的是數據, 流 講的是計算(用於操做數據源,集合,數組)所生成的元素序列。**
                
         Stream API位於 java.util.stream.* 包下。

1 Stream 本身不會存儲元素java

2 Stream 不會改變源對象。相反,他們會返回一個持有結果的性Sstream 。
                  3 Stream 操做是延遲執行的。這覺得這他們會等到須要結果的時候才執行(延遲加載)。

一 建立裏Stream 流的四種方式

### 1 第一種 經過Collection得Stream()方法(串行流)或者 parallelStream()方法(並行流)建立Stream。api

List<String> list = Arrays.asList("1","2","3","4","0","222","33");
        Stream<String> stream = list.stream();
         Stream<String> stream1 = list.parallelStream();

### 2 經過Arrays中得靜態方法stream()獲取數組流數組

IntStream stream = Arrays.stream(new int[]{1,2,3});

### 3 經過Stream類中得 of()靜態方法獲取流網絡

Stream<String> stream = Stream.of("a","b","c");

### 4 建立無限流(迭代、生成)dom

//迭代(須要傳入一個種子,也就是起始值,而後傳入一個一元操做)
     Stream<Integer> stream1 = Stream.iterate(2, (x) -> x * 2);

     //生成(無限產生對象)
     Stream<Double> stream2 = Stream.generate(() -> Math.random());

二 Stream 中間操做

多箇中間操做能夠鏈接起來造成一個流水線,除非流水線終止操做,不然中間操做不會執行任何處理。
終止操做時一次性所有處理,稱爲「延遲加載」

1 篩選切片

1 過濾
List<String> list = Arrays.asList("1","2","3","4","0","222","33");
Stream<String> stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操做。");
            return x.equals("3");
        });
        //終止操做:只有執行終止操做纔會執行所有。即:延遲加載
        stream.forEach(System.out::println);

結果ide

api  中建操做。
 api  中建操做。
 api  中建操做。
3
 api  中建操做。
 api  中建操做。
 api  中建操做。
 api  中建操做。
2 limit() 截斷流,使其元素不超過給定數量。
List<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream<String> stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操做。");
            return x.equals("3");
        });
        //取兩個 , 能夠配合其餘得中間操做,並截斷流,取到相應的元素個數,這不會往下執行,能夠提升效率
        stream.limit(2).forEach(System.out::println);

3 skip(n) 跳過元素

skip(n),返回一個扔掉了前n個元素的流。若流中元素不足n個,則返回一個空,與limit(n)互補。函數

List<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
        Stream<String> stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操做。");
            return x.equals("3");
        });
        //skip(n),返回一個扔掉了前n個元素的流。若流中元素不足n個,則返回一個空,與limit(n)互補。
        stream.skip(3).limit(1).forEach(System.out::println);

4 篩選

    distinct 經過流所生成元素的hashCode()和equals()去除重複元素this

List<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream<String> stream = list.stream();
        stream.distinct().forEach(System.out::println);
1
2
3
4
0
222
33

5 映射

map - 接受lambda 將元素轉換爲其餘形式或提取信息。code

接受一個函數做爲參數,該函數會被應用到每一個元素上,並將其映射成一個新元素

flatMap 接受一個函數做爲參數,將流中的每一個值都轉成另外一個流,而後把全部流連成一個流。對象

List<Stu> stuList = Arrays.asList(new Stu("a",1),new Stu("ab",3),new Stu("c",11),new Stu("f",12));
 
   Stream<Stu> stream = stuList.stream();
        //去除list中全部的年齡
        stream.map(Stu::getAge).forEach(System.out::println);
        //把全部年齡再返回一個集合
        List<Integer> collect = stream.map(Stu::getAge).collect(Collectors.toList());

        stream.flatMap(stu -> test1.filterCharacter(stu.getName())).forEach(System.out::println);

6 排序

sorted有兩種方法,一種是不傳任何參數,叫天然排序,還有一種須要傳Comparator 接口參數,叫作定製排序。

//天然排序
        List<String> collect = list.stream().sorted().collect(Collectors.toList());
        
        List<String> collect2 = list.stream().sorted((o1, o2) -> {
            if(o1.length()>o2.length()){
                return 1;
            }else 
            if(o1.length()<o2.length()){
                return -1;
            }else {
                return 0;

            }
        }).collect(Collectors.toList());

三 Stream 終止操做

實體類

public class Person {
    String name ;
    String sex ;
    int age;
    Status statusEnum;

    public Person(String name, String sex, int age, Status statusEnum) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.statusEnum = statusEnum;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Status getStatusEnum() {
        return statusEnum;
    }

    public void setStatusEnum(Status statusEnum) {
        this.statusEnum = statusEnum;

}

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", statusEnum=" + statusEnum +
                '}';
    }
}

操做

List<Person> persons = Arrays.asList(
                          new Person("張三", "男", 76, Status.FREE),
              new Person("李四", "女", 12, Status.BUSY),
               new Person("王五", "男", 35, Status.BUSY),
               new Person("趙六", "男", 3, Status.FREE),
               new Person("錢七", "男", 56, Status.BUSY),
               new Person("翠花", "女", 34, Status.VOCATION),
               new Person("翠花", "女", 34, Status.FREE),
               new Person("翠花", "女", 34, Status.VOCATION)
              );

1 查找與匹配

##### 1 allMatch —— 檢查是否匹配全部元素。

public void test1(){
        boolean allMatch = persons.stream().allMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
2 anyMatch —— 檢查是否至少匹配一個元素。
public void test2(){
        boolean allMatch = persons.stream().anyMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
3 noneMatch —— 檢查是否沒有匹配全部元素。
檢查 全部的是否都是 FREE  ----- 結果是false
public void test3(){
        boolean allMatch = persons.stream().noneMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
4 findFirst —— 返回第一個元素。
public void test4(){
      Optional<Person> first = persons.stream().findFirst();

      System.out.println(first.get());
  }

##### 5 findAny —— 返回當前流中任意元素。

public void test5(){
     Optional<Person> first = persons.stream().findAny();
     //first.orElse(new Person());  若是沒空 能夠穿一個新的對象去代替它
     System.out.println(first.get());
 }

##### 6 count —— 返回流中元素總個數。

public void test6(){
      long first = persons.stream().count();
      System.out.println(first);
  }

##### 7 max —— 返回流中最大值。

public void test7(){
     Optional<Person> person = persons.stream().max((x,y) ->  Integer.compare(x.age, y.age));
     System.out.println(person.get());
 }

##### 8 min —— 返回流中最小值。

public void test8(){
      Optional<Person> person = persons.stream().min((x,y) ->  Integer.compare(x.age, y.age));
      System.out.println(person.get());
  }

2 歸約 : 能夠將流中元素反覆結合在一塊兒,獲得一個值

1 reduce(T identitty,BinaryOperator)首先,須要傳一個起始值,而後,傳入的是一個二元運算。
public void test9(){
       List<Integer> list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
               // identitty 起始值 0  而後與集合中的值進行 相應的運算,再次賦值給 identity 而後 在進行運算。
                Integer sum = list.stream().reduce(0, (x, y) -> x + y);
       System.out.println(sum);
   }

##### 2 reduce(BinaryOperator)此方法相對於上面方法來講,沒有起始值,則有可能結果爲空,因此返回的值會被封裝到Optional中。

map和reduce的鏈接一般稱爲map-reduce模式,因Google用它來進行網絡搜索而出名。

用map 來提取 對象中某個屬性,而後再用reduce 進行歸約。
public void test10() {
        Optional<Integer> reduce = persons.stream().map(Person::getAge).reduce(Integer::sum);
        System.out.println(reduce.get());
    }
3 收集 : 收集collect(將流轉換爲其餘形式。接收一個Collector接口得實現,用於給其餘Stream中元素作彙總的方法)
Collector接口中方法得實現決定了如何對流執行收集操做(如收集到List,Set,Map)。
       可是Collectors實用類提供了不少靜態方法,能夠方便地建立常見得收集器實例。
1 Collectors.toList() 將流轉換成List
public void test11() {
     List<Person> collect = persons.stream().collect(Collectors.toList());
     collect.forEach(System.out::println);
 }

###### 2 將流轉換成HashSet

public void test12() {
      //hashset會去重複
          Set<String> collect = persons.stream().map(Person::getName).collect(Collectors.toSet());
          collect.forEach(System.out::println);
      }

###### 3 將流轉換成其餘集合

public void test13() {

      Set<Integer> collect = persons.stream().map(Person::getAge).collect(Collectors.toCollection(LinkedHashSet::new));
      collect.forEach(System.out::println);
  }

##### 4 Collectors.counting() 元素個數

public void test14() {

      Long collect = persons.stream().map(Person::getAge).collect(Collectors.counting());
      System.out.println(collect);
  }

##### 5 將流轉換爲其餘形式 , 接受一個conllectors接口的實現,用於給Stream中元素作彙總的方法

public void test14s() {
        // 1 對元素進行彙總方法
        DoubleSummaryStatistics collect = persons.stream().collect(Collectors.summarizingDouble(Person::getAge));
        IntSummaryStatistics collect2 = persons.stream().collect(Collectors.summarizingInt(Person::getAge));
        System.out.println(collect.getMax());
        System.out.println(collect.getAverage());
        System.out.println(collect.getCount());
        System.out.println(collect.getMin());
        System.out.println(collect.getSum());

###### 2 講元素轉換爲其餘形式

String collect1 = persons.stream().map(Person::getName).collect(Collectors.joining(",","頭","尾"));
        String collect3 = persons.stream().map(Person::getName).collect(Collectors.joining());
        System.out.println(collect1); //頭張三,李四,王五,趙六,錢七,翠花,翠花,翠花尾
        System.out.println(collect3); // 張三李四王五趙六錢七翠花翠花翠花
    }
1. Collectors.averagingDouble()
    2  Collectors.averagingDouble()
    3 Collectors.averagingLong()

    平均數,這三個方法均可以求平均數,不一樣之處在於傳入得參數類型不一樣,返回值都爲Double
public void test15() {

        Double s = persons.stream().collect(Collectors.averagingDouble(Person::getAge));
        System.out.println(s);
    }

##### 8 Collectors.maxBy() 求最大值

public void test16() {

          Optional<Person> collect = persons.stream().collect(Collectors.maxBy((o1, o2) -> Integer.compare(o1.age, o2.age)));
          System.out.println(collect.get().age);
      }

##### 9 Collectors.minBy() 求最小值

public void test17() {

     Optional<Person> collect = persons.stream().collect(Collectors.minBy((o1, o2) -> Integer.compare(o1.age, o2.age)));
     System.out.println(collect.get().age);
 }
10 Collectors.groupingBy()分組 ,返回一個map
按照 Status 分組
public void test18() {

      Map<Status, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum));
      collect.forEach((status, people) -> {
          System.out.println(" status === " + status);
          people.forEach(System.out::println);
      });
  }

###### 11 多級分組

Collectors.groupingBy()還能夠實現多級分組
public void test19() {

     Map<Status, Map<String, List<Person>>> collect = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum,Collectors.groupingBy(Person::getSex)));
     Map<Status, Map<String, List<Person>>> collect2 = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum,Collectors.groupingBy(
             e->{
                 if (e.getAge()>10){
                     return "小孩";
                 }else {
                     return "大人";
                 }
             }
     )));
     System.out.println(collect);
     System.out.println(collect2);
 }

##### 12 分區

Collectors.partitioningBy() 分區,參數中傳一個函數,返回true,和false 分紅兩個區
public void test20() {
    年齡大於39的分區  不知足再的分區
Map<Boolean, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(e -> e.getAge() > 30));

      System.out.println(collect);
  }
相關文章
相關標籤/搜索