Java8-14-stream特化流以及如何构建流

本系列文章来自CSDN

原文地址:

https://blog.csdn.net/ryo1060732496/article/details/88806342

  1. 特化的原因并不在于流的复杂性,而是装箱造成的复杂性——即类似 int 和 Integer 之间的效率差异。
  2. 构建流

特化流

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);

猜你喜欢

转载自blog.csdn.net/weixin_43298913/article/details/106139270
今日推荐