import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.IntSupplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* 构建流
*/
public class StreamDemo{
public static void main(String[] args){
//有值创建流
Stream<String> stream = Stream.of("Hello","World");
stream.map(String::toUpperCase).forEach(System.out::println);
//得到一个空流
Stream<String> emptyStream = Stream.empty();
//数组创建流
int[] numbers = {1, 2, 3, 4, 5};
int sum = Arrays.stream(numbers).sum();
System.out.println(sum);
//由文件生成流
//Java中用于处理文件等I/O操作的NIO API(非阻塞 I/O)
long uniqueWords = 0;
try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){//流会自动 关闭
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))//生成单词流
.distinct()//删除重复项
.peek(System.out::println)//窥视
.count();//数一数有多少个不相同的单词
}catch (Exception e){
e.printStackTrace();
}
System.out.println(uniqueWords);
//由函数生成流:创建无限流
//Stream API提供了两个静态方法来从函数生成流:Stream.iterate和Stream.generate。 这两个操作可以创建所谓的无限流
//使用limit(n)来对这种流加以限制,以避免打印无穷多个值
//迭代
//生成了一个所有正偶数的流
Stream.iterate(0,n->n+2)//iterate方法接受一个初始值(在这里是0)
.limit(10)
.forEach(System.out::println);//调用forEach终端操作来消费流,并分别打印每个元素
//斐波纳契元组序列
Stream.iterate(new int[]{0, 1},t->new int[]{t[1],t[0]+t[1]})//iterate的方法则是纯粹不变的:它没有修改现有状态
.limit(20)
.map(t->t[0])
.forEach(System.out::println);//0, 1, 1, 2, 3, 5, 8, 13, 21, 34...
//generate方法也可让你按需生成一个无限流,但generate不是依次 对每个新生成的值应用函数的
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
//Lambda允许你创建函数式接口的实例,只要直接内联提供方法的实 现就可以
//generate方法将使用给定的供应源,并反复调用getAsInt方法,而这个方法总是返回2
IntStream twos = IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return 2;
}
});
//generate实现斐波纳契数列
IntSupplier fib = new IntSupplier() {//此对象有可变的状态
private int previous = 0;
private int current = 1;
@Override
public int getAsInt() {//getAsInt在调用时会改变对象的状态
int oldPrevious = this.previous;
int nextValue = this.previous + this.current;
this.previous = this.current;
this.current = nextValue;
return oldPrevious;
}
};
IntStream.generate(fib).limit(10).forEach(System.out::println);
//终端操作(这里是forEach)将永远计算下去。同样,你不能对无限流 做排序或归约,因为所有元素都需要处理
//应该始终采用不变的方法,以便并行处理流,并保持结果正确
}
}