本系列文章来自CSDN
原文地址:
https://blog.csdn.net/ryo1060732496/article/details/88806342
- 特化的原因并不在于流的复杂性,而是装箱造成的复杂性——即类似 int 和 Integer 之间的效率差异。
- 构建流
特化流
Java 8引入了三个原始类型特化流接口来解决装箱造成的复杂性: IntStream、 DoubleStream 和 LongStream ,分别将流中的元素特化为 int 、 long 和 double ,从而避免了暗含的装箱成本。
每个接口都带来了进行常用数值归约的新方法,比如对数值流求和的 sum,找到最大元素的max。
1. 映射到数值流(mapToInt)
// 按照之前的归约 reduce 来计算总和,它有一个暗含的装箱成本,每个 Integer 都必须拆箱成一个原始类型,再进行求和
int calories = Restaurant.menu.stream()
.map(Dish::getCalories)
.reduce(0, Integer::sum);
// 映射到数值流
calories = Restaurant.menu.stream()
.mapToInt(Dish::getCalories)
.sum();
System.out.println(calories);
2. 转换回对象流(boxed)
IntStream intStream = Restaurant.menu.stream().mapToInt(Dish::getCalories);
Stream<Integer> boxed = intStream.boxed();
3. 默认值(OptionalInt)
如果流为空,则sum默认为0;max,min返回OptionalInt
OptionalInt max = Restaurant.menu.stream().mapToInt(Dish::getCalories).max();
int i = max.orElse(1);
// 800
System.out.println(i);
// OptionalInt[800]
System.out.println(max);
数值范围
Java 8引入了两个可以用于 IntStream 和 LongStream 的静态方法,帮助生成这种范围:range(不包含结束值) 和 rangeClosed(包含结束值)
IntStream evenNumbers = IntStream.rangeClosed(1, 100).filter(x -> x % 2 == 0);
System.out.println(evenNumbers.count());
构建流
1. 由值创建流(Stream.of())
Stream<String> stringStream = Stream.of("Java","Hello","World");
stringStream.map(String::toUpperCase).forEach(System.out::println);
2. 创建空流(Stream.empty())
Stream<?> emptyStream = Stream.empty();
3. 由数组创建流(Arrays.stream())
int[] ints = {2,4,6,7,8};
int sum = Arrays.stream(ints).sum();
System.out.println(sum);
4. 由文件生成流
java.nio.file.Files 中的很多静态方法都会返回一个流
long uniqueWords;
try(Files.lines(Paths.get(ClassLoader.getSystemResource("data.txt").toURI()), Charset.defaultCharset())) {
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
.distinct()
.count();
System.out.println("uniqueWords:" + uniqueWords);
}catch (IOException e) {
e.fillInStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
5. 由函数生成流
Stream API提供了两个静态方法来从函数生成流: Stream.iterate() 和 Stream.generate() 这两个操作可以创建所谓的无限流:不像从固定集合创建的流那样有固定大小的流
一般来说,应该使用 limit(n) 来对这种流加以限制,以避免打印无穷多个值
Stream.iterate(0,n -> n+2).limit(10).forEach(System.out::println);
Stream.generate(Math::random).limit(5).forEach(System.out::println);