Java 8之數值流使用和構建流的方式

數值流:

數值流,顧名思義就是專門用來操做基礎數據類型的流,那它的做用是什麼呢?先看下面的代碼。這段代碼是獲取集合每一個對象的num字段的值,而後求所和。得出的結果是15,看上去沒有問題,可是要注意的是流在進行求和操做的時候從對象中取出來的是基本類型,會進行裝箱操做變成Integer類型再進行求和,性能會有所降低,而數值流就是專門對基本類型數據進行操做的。數組

public class DataStream {
    public static void main(String[] args){
        List<Num> list = new ArrayList<Num>();
        Num num1 = new Num(1);
        Num num2 = new Num(2);
        Num num3 = new Num(3);
        Num num4 = new Num(4);
        Num num5 = new Num(5);
        list.add(num1);
        list.add(num2);
        list.add(num3);
        list.add(num4);
        list.add(num5);
        System.out.println(list.stream().map(Num::getNum).reduce(Integer::sum));
    }
}

class Num{
    private int num;

    public Num(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

數值流的使用:

1.想要使用數值流其實很簡單,只須要調用Stream.mapToInt()方法就能夠得到一個數值流了,咱們會發現數值流有更多的封裝好的計算方法,更加方便咱們對數值的計算。dom

System.out.println(list.stream().mapToInt(Num::getNum).count());
System.out.println(list.stream().mapToInt(Num::getNum).sum());
System.out.println(list.stream().mapToInt(Num::getNum).max());
System.out.println(list.stream().mapToInt(Num::getNum).min());
System.out.println(list.stream().mapToInt(Num::getNum).average());

運行結果:函數

5
15
OptionalInt[5]
OptionalInt[1]
OptionalDouble[3.0]

2.須要注意的是maxminaverage方法若是在流爲空的時候獲取不到值會返回空的Optional對象,而countsum方法則是返回0。性能

運行結果:this

0
0
OptionalInt.empty
OptionalInt.empty
OptionalDouble.empty

3.有時候咱們可能會想將數值流轉換回原來的流,咱們能夠調用boxed()方法。code

public static void changeStream(){
    int[] arr = new int[]{1,2,3,4,5};
    IntStream intStream =  Arrays.stream(arr);
    Stream<Integer> stream = intStream.boxed();
}

4.上面咱們介紹的是IntStream,它專門用來處理int類型的數值,除此以外還有DoubleStreamLongStream,它們分別處理doublelong類型的數值,只要調用mapToDoublemapToLong方法便可得到對應的數值流,使用方法也是IntStream大同小異,這裏就不作詳細介紹了。對象


構建流:

以前的文章中咱們一直都是直接調用集合的stream方法來獲取一個流,其實獲取流的方式有不少種。get

  1. 直接使用值初始化流it

    public static void valueStream(){
        Stream<String> stream = Stream.of("Hello", "World ");
        stream.map(String::toUpperCase).forEach(System.out::println);
    }
  2. 使用Arrays.stream()靜態方法建立流,這個方法接受一個數組io

    public  static void arrayStream(){
        String[] strs = new String[]{"Hello","World"};
        Arrays.stream(strs).map(String::toUpperCase).forEach(System.out::println);
    }
  3. 從文件中讀取獲取流,每一行就是流中的一個元素

    public static void fileStream(){
        try {
            Stream<String> text = Files.lines(Paths.get("C:\\Users\\Half\\Desktop\\test.txt"),Charset.defaultCharset());
            text.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  4. 用函數生成無限流,分別調用Stream.iterate()Stream.generate()方法便可,二者不一樣之處在於Stream.iterate()方法沒生成一個值都要依賴於前一個值,適合生成連續的數值,而Stream.generate()則每一個值都是獨立生成的,相互之間沒有關聯。要注意的是由於是無限流,因此會一直生成元素,因此必需要調用limit()方法來限制生成的個數,不然代碼會一直運行下。

    • Stream.iterate()接受兩個參數,分別是起始值和後續值的生成代碼,例以下面這個方法就是從0開始,依次加10

      public static void iterateStream(){
          Stream.iterate(0, num -> num+10).limit(5).forEach(System.out::println);
      }

      運行結果:

      0
      10
      20
      30
      40
    • Stream.generate()接受一個參數,生成數值的代碼

      public static void generateStream(){
          Stream.generate(Math::random).limit(5).forEach(System.out::println);
      }

      運行結果:

      0.9538068193407456
      0.5113995186169759
      0.20525086606957266
      0.2974528805300197
      0.019653649898021208

總結:

這篇文章介紹了數值流和構建流的方式,流的應用能夠很靈活,後續還會介紹流的用法。

相關文章
相關標籤/搜索