数值流,顾名思义就是专门用来操做基础数据类型的流,那它的做用是什么呢?先看下面的代码。这段代码是获取集合每一个对象的num
字段的值,而后求所和。得出的结果是15,看上去没有问题,可是要注意的是流在进行求和操做的时候从对象中取出来的是基本类型,会进行装箱操做变成Integer
类型再进行求和,性能会有所降低,而数值流就是专门对基本类型数据进行操做的。数组
public class DataStream { public static void main(String[] args){ List<Num> list = new ArrayList<Num>(); Num num1 = new Num(1); Num num2 = new Num(2); Num num3 = new Num(3); Num num4 = new Num(4); Num num5 = new Num(5); list.add(num1); list.add(num2); list.add(num3); list.add(num4); list.add(num5); System.out.println(list.stream().map(Num::getNum).reduce(Integer::sum)); } } class Num{ private int num; public Num(int num) { this.num = num; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
1.想要使用数值流其实很简单,只须要调用Stream.mapToInt()
方法就能够得到一个数值流了,咱们会发现数值流有更多的封装好的计算方法,更加方便咱们对数值的计算。dom
System.out.println(list.stream().mapToInt(Num::getNum).count()); System.out.println(list.stream().mapToInt(Num::getNum).sum()); System.out.println(list.stream().mapToInt(Num::getNum).max()); System.out.println(list.stream().mapToInt(Num::getNum).min()); System.out.println(list.stream().mapToInt(Num::getNum).average());
运行结果:函数
5 15 OptionalInt[5] OptionalInt[1] OptionalDouble[3.0]
2.须要注意的是max
、min
和average
方法若是在流为空的时候获取不到值会返回空的Optional
对象,而count
和sum
方法则是返回0。性能
运行结果:this
0 0 OptionalInt.empty OptionalInt.empty OptionalDouble.empty
3.有时候咱们可能会想将数值流转换回原来的流,咱们能够调用boxed()
方法。code
public static void changeStream(){ int[] arr = new int[]{1,2,3,4,5}; IntStream intStream = Arrays.stream(arr); Stream<Integer> stream = intStream.boxed(); }
4.上面咱们介绍的是IntStream
,它专门用来处理int
类型的数值,除此以外还有DoubleStream
和LongStream
,它们分别处理double
和long
类型的数值,只要调用mapToDouble
和mapToLong
方法便可得到对应的数值流,使用方法也是IntStream
大同小异,这里就不作详细介绍了。对象
以前的文章中咱们一直都是直接调用集合的stream
方法来获取一个流,其实获取流的方式有不少种。get
直接使用值初始化流it
public static void valueStream(){ Stream<String> stream = Stream.of("Hello", "World "); stream.map(String::toUpperCase).forEach(System.out::println); }
使用Arrays.stream()
静态方法建立流,这个方法接受一个数组io
public static void arrayStream(){ String[] strs = new String[]{"Hello","World"}; Arrays.stream(strs).map(String::toUpperCase).forEach(System.out::println); }
从文件中读取获取流,每一行就是流中的一个元素
public static void fileStream(){ try { Stream<String> text = Files.lines(Paths.get("C:\\Users\\Half\\Desktop\\test.txt"),Charset.defaultCharset()); text.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } }
用函数生成无限流,分别调用Stream.iterate()
和Stream.generate()
方法便可,二者不一样之处在于Stream.iterate()
方法没生成一个值都要依赖于前一个值,适合生成连续的数值,而Stream.generate()
则每一个值都是独立生成的,相互之间没有关联。要注意的是由于是无限流,因此会一直生成元素,因此必需要调用limit()
方法来限制生成的个数,不然代码会一直运行下。
Stream.iterate()
接受两个参数,分别是起始值和后续值的生成代码,例以下面这个方法就是从0开始,依次加10
public static void iterateStream(){ Stream.iterate(0, num -> num+10).limit(5).forEach(System.out::println); }
运行结果:
0 10 20 30 40
Stream.generate()
接受一个参数,生成数值的代码
public static void generateStream(){ Stream.generate(Math::random).limit(5).forEach(System.out::println); }
运行结果:
0.9538068193407456 0.5113995186169759 0.20525086606957266 0.2974528805300197 0.019653649898021208
这篇文章介绍了数值流和构建流的方式,流的应用能够很灵活,后续还会介绍流的用法。