这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
Stream是什么
Stream是一个高级的迭代器,不会存数据,Stream关注的是怎么把数据高效的处理,类似于生活中的流水线。
外部迭代内部迭代
public static void main(String[] args) {
int[] nums = {1,2,3};
//外部迭代
int sum =0;
for (int i:nums
) {
sum+=i;
}
System.out.println("结果为"+sum);
//内部迭代
int sum2 = IntStream.of(nums).sum();
System.out.println("结果为:" +sum2);
}
外部迭代的缺点:1.需要自己写过程 2.上述外部迭代的代码是串行的效率低
中间操作、终止操作、惰性求值
将原来的数X2
int sum2 = IntStream.of(nums).map(i->i*2).sum();
System.out.println("结果为:" +sum2);
这里map 就是中间操作, 也就是返回流的操作 sum就是 终止操作返回一个结果
import java.util.stream.IntStream;
public class StreamDemo {
public static void main(String[] args) {
int[] nums = {1,2,3};
//外部迭代
int sum =0;
for (int i:nums
) {
sum+=i;
}
System.out.println("结果为"+sum);
int sum2 = IntStream.of(nums).map(StreamDemo::doubleNum).sum();
System.out.println("结果为:" +sum2);
System.out.println("惰性操作就是终止没有调用的情况下,中间操作不会执行");
IntStream.of(nums).map(StreamDemo::doubleNum);
}
public static int doubleNum(int i){
System.out.println("执行了X2 ");
return i*2;
}
}
int sum2 = IntStream.of(nums).map(StreamDemo::doubleNum).sum();这里调用了 sum 所以执行了 3次 X2
但是
IntStream.of(nums).map(StreamDemo::doubleNum);
没有调用终止操作,所以不被调用
流操作
直接上代码
public class StreamDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//从集合中创建
list.stream();
list.parallelStream();
//从数组中创建
Arrays.stream(new int[]{2,3,5});
//创建数字流
IntStream.of(1,2,3);
IntStream.rangeClosed(1,10);//相当于边界
//使用random 创建一个无线流
new Random().ints().limit(10);
//自己手动创建
Random random = new Random();
Stream.generate(()-> random.nextInt()).limit(20);
}
}
流的中间操作
中间操作有两种 :无状态操作和有状态操作
无状态操作: 操作和其他的值无关 有状态操作:状态要等待流结束才给出最终结果
public class StreamDemo3 {
public static void main(String[] args) {
String str = "my name is 007";
//把每个单词长度调用出来
Stream.of(str.split(" ")).filter(s->s.length()>2).map(s->s.length()).forEach(System.out::println);
//flatMap A-> B 属性 (A是个集合) 最终得到,所有A元素里面所有属于B元素的集合
//IntStream /longStream 并不是Stream的子类 ,所以要进行装箱
Stream.of(str.split(" ")).flatMap(s->s.chars().boxed()).forEach(
i->System.out.println((char) i.intValue())
);
//peek 一般用于debug.是个中间操作,和forEach是终止操作
Stream.of(str.split(" ")).peek(System.out::println).forEach(System.out::println);
//limit 使用 ,主要是使用无线流 如果不做限制会一直进行下去
new Random().ints().filter(i->i>100 && i<1000).limit(10)
.forEach(System.out::println);
}
}