P31
程序清单1-7 streams/PrimitiveTypeStreams.java


  1. 代码
  2. 分析

1.代码

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class PrimitiveTypeStreams
{
   public static void show(String title, IntStream stream)
   {
      //将流stream中的前11个元素存入firstElements数组
      final int SIZE = 10;
      int[] firstElements = stream.limit(SIZE + 1).toArray();
      System.out.print(title + ": ");

      //打印数组前SIZE项
      for (int i = 0; i < firstElements.length; i++)
      {
         if (i > 0) System.out.print(", ");
         if (i < SIZE) System.out.print(firstElements[i]);
         else System.out.print("...");
      }
      System.out.println();
   }

   public static void main(String[] args) throws IOException
   {
      //构造一个元素为0-100内的整数的无限流
      IntStream is1 = IntStream.generate(() -> (int) (Math.random() * 100));
      show("is1", is1);

      //构造一个元素在[5,10)区间的有限流(五个元素,区间左闭右开)
      IntStream is2 = IntStream.range(5, 10);
      show("is2", is2);

      //构造一个元素在[5,10)区间的有限流(五个元素,区间左闭右闭)
      IntStream is3 = IntStream.rangeClosed(5, 10);
      show("is3", is3);

      //读取alice30.txt内容并存入contents(以UTF-8编码方式)
      Path path = Paths.get("../gutenberg/alice30.txt");
      String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);

      //将contents分隔为单词并存入words字符串流
      Stream<String> words = Stream.of(contents.split("\\PL+"));

      //将words每个元素一一通过String::length映射(即求出每个元素的长度)并存入is4整形流
      IntStream is4 = words.mapToInt(String::length);
      show("is4", is4);

      /*
      * 编者认为这一段没有多大实用价值,就不作解释了…具体请参照书本P30
      String sentence = "\uD835\uDD46 is the set of octonions.";
      System.out.println(sentence);
      IntStream codes = sentence.codePoints();
      System.out.println(codes.mapToObj(c -> String.format("%X ", c)).collect(
            Collectors.joining()));
      */

      //创建从0到99的整形流(基本类型流)并将之通过boxed方法转换为整形流(对象流)
      Stream<Integer> integers = IntStream.range(0, 100).boxed();

      //将对象流integers重新映射回基本类型流is5
      IntStream is5 = integers.mapToInt(Integer::intValue);
      show("is5", is5);
   }
}

alice30.txt:(这里仅截取一部分)

We produce about two million dollars for each hour we work.  The
fifty hours is one conservative estimate for how long it we take
to get any etext selected, entered, proofread, edited, copyright
searched and analyzed, the copyright letters written, etc.  This
projected audience is one hundred million readers.  If our value
per text is nominally estimated at one dollar then we produce $4
million dollars per hour this year as we release some eight text
files per month:  thus upping our productivity from $2 million.

2.分析


show(String title, IntStream stream)方法:
将整形流(基本类型流)stream遍历输出(打印前10项,若未打印完全则用省略号表示)
public static void show(String title, IntStream stream)
   {
      //将流stream中的前11个元素存入firstElements数组
      final int SIZE = 10;
      int[] firstElements = stream.limit(SIZE + 1).toArray();
      System.out.print(title + ": ");

      //打印数组前SIZE项
      for (int i = 0; i < firstElements.length; i++)
      {
         if (i > 0) System.out.print(", ");
         if (i < SIZE) System.out.print(firstElements[i]);
         else System.out.print("...");
      }
      System.out.println();
   }

回到main函数

这里仅讲一下mapToInt(ToIntFunction<? super T> mapper)方法,其他内容请参照重要API佐证理解:
看一下这两行代码:

// Stream<String> words
// Stream<Integer> integers
IntStream is4 = words.mapToInt(String::length);
IntStream is5 = integers.mapToInt(Integer::intValue);

让我们看一下mapToInt(ToIntFunction<? super T> mapper)的源码:

public interface Stream<T> extends BaseStream<T, Stream<T>> {
    IntStream mapToInt(ToIntFunction<? super T> mapper);
}

mapToInt(ToIntFunction<? super T> mapper)是一个专用于返回整形流(基本类型流)的方法。

让我们再看一下它的参数ToIntFunction<? super T> mapperToIntFunction<? super T>的源码:

@FunctionalInterface
public interface ToIntFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(T value);
}

这是一个函数式接口。

由此可见,程序清单中的mapToInt(String::length)是覆写了applyAsInt(T value)方法,实现一个从对象流到整形流的转换。


如有谬误或不完善之处,恳请斧正。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐