列举创建Stream<T>、IntStream(LongStream、DoubleStream)对象的一些常见例子。
1.by Values or Collection
(1)因为Stream<T>的静态方法of
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
通过一系列值创建流对象,与Arrays.stream(重载)一致,两者放在一起。
Stream<T> of(T... values) 按照参数类型创建Stream<T> 对象。如Stream<String>、Stream<Integer>
Stream<T> of(T t)按照参数类型创建只有一个元素的流对象。
(2)Arrays.stream()
Arrays.stream(int[] array) 创建IntStream流对象(long[]、double[]类似),注意不是Stream<Integer>。
Arrays.stream(T[] array)对象数组为参数创建Stream<T> ,如Stream<String>。
对于集合,使用Collection<E>的默认方法stream()
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
public static void fromValues() {
Stream<String> s = Stream.of("create", "Stream", "by", "Stream.of");
Stream<Integer> s2 = Stream.of(1,2,3);
int[] array = {1, 2, 3};
Stream<int[]> s3 = Stream.of(array);
s3.forEach(System.out::println); //[I@1c20c684
}
public static void fromCollection() {
int[] array = {1, 2, 3};
IntStream stream = Arrays.stream(array);//注意
int sum = stream.sum();
String[] strArray = {"a","b"};
Stream<String> stream1 = Arrays.stream(strArray);
List<String> myList = Arrays.asList("a1", "a2","a1");
Stream<String> stream2 = myList.stream();
stream2.forEach(System.out::print); //a1a2a1
System.out.println();
HashSet<String> set = new HashSet<>(myList);
Stream<String> stream3 = set.stream();
stream3.forEach(System.out::print); //a1a2
}
从值、数组和List、Set等创建流对象,是最基本的。
2.无限流
Stream的静态方法iterate和generate可以创建无限流,因此需要在适当的时候限制一下流元素的长度。
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
public static<T> Stream<T> generate(Supplier<T> s)
iterate的种子的类型决定了流的类型参数,一元操作不断应用于前一个元素。
generate使用一个Supplier<T>作为产生无限流的依据。下面例子分别使用了
Supplier<String> supplier =()->{return "a";};
和Math的random()函数。
public static void infiniteStream() {
Stream<Integer> stream_int = Stream.iterate(0, n -> n + 2);
stream_int.limit(5).forEach(s -> System.out.print(s + " "));
System.out.println();
Stream<String> stream_str = Stream.iterate("a", s -> s + "a");
stream_str.limit(5).forEach(s -> System.out.print(s + " "));
System.out.println();
Stream<Double> stream_double = Stream.generate(Math::random).limit(3);
stream_double.forEach(s -> System.out.print(s + " "));
System.out.println();
Supplier<String> supplier =()->{return "a";};
Stream<String> stream_str2 = Stream.generate(supplier).limit(3);
stream_str2.forEach(s -> System.out.print(s + " "));
}
输出:
0 2 4 6 8
a aa aaa aaaa aaaaa
0.537544433840739 0.18913558672368358 0.007618540214730407
a a a
打印Fibonacci数列的前10项。iterate的种子new int[]{0, 1},产生 (0,1), (1, 1), (1,2), (2, 3), (3, 5), (5, 8), (8, 13), (13, 21)...流
Stream<int[]> iterate = Stream.iterate(new int[]{0, 1},
t -> new int[]{t[1], t[0] + t[1]});
iterate.limit(10).forEach(t -> Print.pln(t));
注:
Print有方法
public static void pln(int[] arr){
System.out.println(java.util.Arrays.toString(arr));
}
输出:
[0, 1]
[1, 1]
[1, 2]
[2, 3]
[3, 5]
[5, 8]
[8, 13]
[13, 21]
[21, 34]
[34, 55]
3.范围
对于int和long数据,一个常见的用法是按照一个range,生成IntStream或LongStream对象。
rangeClosed(int startInclusive, int endInclusive) 数学上表示为[a,b];range(int a, int b) 数学上表示为[a,b)。
public static void rangesStream() {
IntStream stream_int = IntStream.rangeClosed(1, 4);
stream_int.forEach(s -> System.out.print(s + " "));
System.out.println();
LongStream.range(1, 4).forEach(s -> System.out.print(s + " "));
}
输出:
1 2 3 4
1 2 3