Java流 – Java函数流
我们可以有一个可以根据需要生成值的函数。
以下两种静态方法从Stream接口从函数生成无限流。
<T> Stream<T> iterate(T seed, UnaryOperator<T> f) <T> Stream<T> generate(Supplier<T> s)
iterate()方法创建顺序有序流。
generate()方法创建一个顺序无序流。
IntStream,LongStream和DoubleStream包含iterate()和generate()方法,它们采用特定于其原始类型的参数生成值。
例如,在IntStream接口中定义了以下两种方法:
IntStream iterate(int seed, IntUnaryOperator f) IntStream generate(IntSupplier s)
Stream.iterate()
iterate()方法有两个参数:种子和函数。
种子是流的第一个元素。通过将函数应用于第一元素来生成第二元素。通过对第二元素应用函数来生成第三元素。
因此,元素是:seed,f(seed),f(f(seed)),f(f(f(seed)))….
以下代码创建了一个自然数流:
Stream<Long> naturalNumbers = Stream.iterate(1L, n -> n + 1);
limit(long maxSize)
操作是产生另一个流的中间操作。
以下代码创建前10个自然数的流:
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); } }
上面的代码生成以下结果。
例2
以下代码过滤从iterate函数生成的值。
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; } }
上面的代码生成以下结果。
例3
要从流中丢弃某些元素,请使用跳过操作。
skip(long n)是一个中间操作,跳过流的前n个元素。
以下代码使用skip跳过前100个奇数:
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; } }
上面的代码生成以下结果。
Stream.generate()
generate(Supplier<T> s)
使用Supplier来生成无限顺序无序流。
例子
以下代码打印五个随机数。
import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream.generate(Math::random) .limit(5) .forEach(System.out::println); } }
上面的代码生成以下结果。
例4
要生成基于上一个元素生成下一个元素的流,您需要使用存储最后生成元素的Supplier。
以下代码保留静态变量中的最后一个值。
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; } }
上面的代码生成以下结果。
随机流
java.util.Random类提供ints(),longs()和doubles()分别返回无限IntStream,LongStream和DoubleStream。
以下代码从从Random类的ints()方法返回的IntStream中打印了五个随机int值:
import java.util.Random; public class Main { public static void main(String[] args) { new Random().ints() .limit(5) .forEach(System.out::println); } }
上面的代码生成以下结果。
例5
我们可以使用Random的nextInt()方法类作为Supplier在generate()方法中实现相同。
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); } }
上面的代码生成以下结果。
例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); } }
上面的代码生成以下结果。
例7
生成重复值的无限流。
import java.util.stream.IntStream; public class Main { public static void main(String[] args) { IntStream.generate(() -> 0) .limit(5) .forEach(System.out::println); } }
上面的代码生成以下结果。