Java 函數(shù)流

2018-03-12 17:20 更新

Java流 - Java函數(shù)流


我們可以有一個(gè)可以根據(jù)需要生成值的函數(shù)。

以下兩種靜態(tài)方法從Stream接口從函數(shù)生成無限流。

<T> Stream<T> iterate(T  seed, UnaryOperator<T>  f)
<T> Stream<T> generate(Supplier<T> s)

iterate()方法創(chuàng)建順序有序流。

generate()方法創(chuàng)建一個(gè)順序無序流。

IntStream,LongStream和DoubleStream包含iterate()和generate()方法,它們采用特定于其原始類型的參數(shù)生成值。

例如,在IntStream接口中定義了以下兩種方法:

IntStream iterate(int seed,  IntUnaryOperator f)
IntStream generate(IntSupplier s)

Stream.iterate()

iterate()方法有兩個(gè)參數(shù):種子和函數(shù)。

種子是流的第一個(gè)元素。通過將函數(shù)應(yīng)用于第一元素來生成第二元素。通過對第二元素應(yīng)用函數(shù)來生成第三元素。

因此,元素是:seed,f(seed),f(f(seed)),f(f(f(seed)))....

以下代碼創(chuàng)建了一個(gè)自然數(shù)流:

Stream<Long> naturalNumbers = Stream.iterate(1L, n -> n + 1);

limit(long maxSize)操作是產(chǎn)生另一個(gè)流的中間操作。

以下代碼創(chuàng)建前10個(gè)自然數(shù)的流:

import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream<Long> tenNaturalNumbers = Stream.iterate(1L, n  ->  n  + 1)
        .limit(10);

    tenNaturalNumbers.forEach(System.out::println);
  }
}

上面的代碼生成以下結(jié)果。

例2

以下代碼過濾從iterate函數(shù)生成的值。

import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream.iterate(2L, n  ->  n  + 1)
    .filter(Main::isOdd)
    .limit(5)
    .forEach(System.out::println);
  }
  public static boolean isOdd(long number) {
    if (number % 2 == 0) {
      return false;
    }
    return true;
  }
}

上面的代碼生成以下結(jié)果。

例3

要從流中丟棄某些元素,請使用跳過操作。

skip(long n)是一個(gè)中間操作,跳過流的前n個(gè)元素。

以下代碼使用skip跳過前100個(gè)奇數(shù):

import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream.iterate(2L, n  ->  n  + 1)
    .filter(Main::isOdd)
    .skip(100)
    .limit(5)
    .forEach(System.out::println);
  }
  public static boolean isOdd(long number) {
    if (number % 2 == 0) {
      return false;
    }
    return true;
  }
}

上面的代碼生成以下結(jié)果。

Stream.generate()

generate(Supplier<T> s)使用Supplier來生成無限順序無序流。

例子

以下代碼打印五個(gè)隨機(jī)數(shù)。

import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream.generate(Math::random)
    .limit(5)
    .forEach(System.out::println);

  }
}

上面的代碼生成以下結(jié)果。

例4

要生成基于上一個(gè)元素生成下一個(gè)元素的流,您需要使用存儲最后生成元素的Supplier。

以下代碼保留靜態(tài)變量中的最后一個(gè)值。

import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream.generate(Main::next)
    .limit(5)
    .forEach(System.out::println);

  }
  
  static int i=0;
  private static int next(){
    i++;
    return i;
  }
}

上面的代碼生成以下結(jié)果。

隨機(jī)流

java.util.Random類提供ints(),longs()和doubles()分別返回?zé)o限IntStream,LongStream和DoubleStream。

以下代碼從從Random類的ints()方法返回的IntStream中打印了五個(gè)隨機(jī)int值:

import java.util.Random;

public class Main {
  public static void main(String[] args) {
    new Random().ints()
    .limit(5)
    .forEach(System.out::println);

  }
}

上面的代碼生成以下結(jié)果。

例5

我們可以使用Random的nextInt()方法類作為Supplier在generate()方法中實(shí)現(xiàn)相同。

import java.util.Random;
import java.util.stream.Stream;

public class Main {
  public static void main(String[] args) {
    Stream.generate(new Random()::nextInt)
    .limit(5)
    .forEach(System.out::println);
  }
}

上面的代碼生成以下結(jié)果。

例6

要僅使用基本值,請使用基本類型流接口的generate()方法。

import java.util.Random;
import java.util.stream.IntStream;

public class Main {
  public static void main(String[] args) {
    IntStream.generate(new Random()::nextInt)
    .limit(5)
    .forEach(System.out::println);

  }
}

上面的代碼生成以下結(jié)果。

例7

生成重復(fù)值的無限流。

import java.util.stream.IntStream;

public class Main {
  public static void main(String[] args) {
    IntStream.generate(() ->  0)
    .limit(5)
    .forEach(System.out::println);
  }
}

上面的代碼生成以下結(jié)果。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號