原始类型Stream
将基本类型(如int, double等)封装成对象,显然是一个低效的做法,Stream API 提供了IntStream,LongStream和DoubleStream来直接存储原始类型值。String类型除外,它只能用Stream<String>来处理。下面是原始类型和对应Stream的映射表。
原始数据类型 |
对应的Stream |
String |
Stream<String> |
short, char, byte, boolean和int |
IntStream |
Long |
LongStream |
Double |
DoubleStream |
注意:shrot, char, byte和boolean,没有专门的Stream,需要时用IntStream。float也没有专门的Stream,需要时使用DoubleStream。
创建原始类型Stream
of()方法指定元素创建。
IntStream intStream = IntStream.of(1, 2, 3); LongStream longStream = LongStream.of(4, 5, 6); DoubleStream doubleStream = DoubleStream.of(0.1, 0.2, 0.3);
short, char, byte可以直接构造成IntStream,folat可以直接构造成DoubleStream,但是boolean类型不能直接构造成IntStream,要手动转换一下。
IntStream charStream = IntStream.of('A', 'B'); IntStream byteStream = IntStream.of((byte) 1, (byte) 2); IntStream shortStream = IntStream.of((short) 1, (short) 2 ); DoubleStream floatStream = DoubleStream.of((float) 0.1, (float) 0.2); // Boolean value cannot automatically be casted to integer. // (Compile fail) IntStream.of(true, false);<br /> IntStream booleanStream = Stream.of(true, false).mapToInt(b -> b ? 1 : 0);
从数组创建原始类型Stream,数组是什么类型,创建的就是什么类型的Stream。Arrays.Stream()方法,只接受int, long, double和对象类型的数组。传入short, char, byte, boolean和float类型的数组,编译不过。
int[] nums = {1, 2, 3}; IntStream numStream = Arrays.stream(nums);
普通Stream转换成原始类型Stream。
class Book { private long id; private int pages; private double price; // Getter and setter } Stream<Book> books = ... LongStream idStream = books.mapToLong(book -> book.getId()); IntStream pagesStream = books.mapToInt(book -> book.getPages()); DoubleStream priceStream = books.mapToDouble(book -> book.getPrice());
IntStream和LongStream,拥有静态方法range()和rangeClosed(),用来产生步进为1的整数范围。
IntStream zeroToNine = IntStream.range(0, 10); //Exclude 10 IntStream zeroToTen = IntStream.rangeClosed(0, 10); //Include 10
Random类提供了ints, longs和doubles方法,来生成随机数的原始类型流。下面是ints用法,longs和doubles用法相同。
Random random = new Random(); // Infinite IntStream ints1 = random.ints(); // Indicate size (5). IntStream ints2 = random.ints(5); // Indicate range [5, 100). 5 is inclusive, 100 is exclusive. IntStream ints3 = random.ints(5, 100); // Indicate size (20) and range [0, 100). IntStream ints4 = random.ints(20, 0, 100);
Optional结果
原始类型Stream,产生Optional的方法会返回一个OptionalInt,OptionalLong或者OptionalDouble。它们没有get()方法,对应的是getAsInt、getAsLong和getAsDouble。
OptionalDouble value = random.doubles(5, 0.01, 1.0).findFirst(); double doubleValue = value.getAsDouble();
对原始Stream,进行数学统计
方法count,sum,average,max和min会返回元素个数,总和,平均值,最大值和最小值。这种统计方法,只能使用一个,因为任何操作都会把Stream关闭掉。
IntStream nums = random.ints(10, 0, 100); OptionalInt max = nums.max(); //Cannot apply min() again. //OptionalInt min = nums.min();
如果想同时统计Stream的最大值、最小值、平均值等,改怎么办?
summaryStatistics()方法,会产生一个IntSummaryStatistics,LongSummaryStatistics或者DoubleSummaryStatistics对象,可以同时获得元素个数、总和、平均值、最大值和最小值。
IntStream nums = random.ints(10, 0, 100); IntSummaryStatistics statistics = nums.summaryStatistics(); long count = statistics.getCount(); long sum = statistics.getSum(); double average = statistics.getAverage(); int max = statistics.getMax(); int min = statistics.getMin();
其它
1. 原始类型Stream的toArray()方法,会返回原始类型的数组,不用传入数组构造器转型。
2. boxed()方法,将原始类型Stream转换成对象Stream
Stream<Integer> boxed = IntStream.of(1, 2, 3).boxed();