Java基础知识拾遗(四)

IO

  SequenceInputStream,允许链接多个InputStream对象。在操作上该类从第一个InputStream对象进行读取,知道读取完全部内容,然后切换到第二个InputStream

  知道最后一个InputStream对象的末尾文职。到达每个文件末尾是,与之关联的流就会被关闭。

  ObjectOutput接口,支持对象序列化。ObjectOutputStream实现了ObjectOutput接口,负责将对象写入流中。

  ObjectInput接口,支持对象串行化。ObjectInputStream实现了ObjectInput接口,读取串行化对象的输入流。

NIO

  NIO系统并非用于替换java.io中基于流的I/O。NIO系统构建于两个基础术语之上:缓冲区和通道。缓冲区用于容纳数据,通道表示打开的到I/O设备的链接。通常,为了

  使用NIO系统,需要获取用于链接I/O设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,根据需要输入或者输出数据。

  缓冲区,是Buffer的子类,定义了对所有缓冲区都通用的核心功能:当前位置、界限和容量。当前位置是缓冲区中下一次发生读取和写入操作的索引,当前位置通过大多数

    读或写向前推进。界限是缓冲区最后一个有效位置之后下一个位置的索引。容量是缓冲区能够容纳的元素的数量。

  MappedByteBuffer是Buffer的子类,用于将文件映射到缓冲区。

  通道,是由java.nio.channels保定义的。表示到I/O源或者目标的打开的链接。通道实现了Channel接口并扩展了Closeable接口和AutoCloseable接口。可以使用带资源的try语句

         管理通道。

  字符集和选择器,字符集定义了将字节映射为字符的方法。可以使用编码器将一系列字符编码成字节,使用解码器将一系列字节解码城字符。字符集、解码器、编码器

    由java.nio.charset包中定义的类支持。因为提供了默认的编码器和解码器,所以通常不需要显示第使用字符集进行工作。

    选择器支持基于键的,非锁定的多通道I/O使用选择器可以通过多个通道执行I/O。选择器最适合用于基于套接字的通道。

  Path接口,封装了文件的路径,Path被打包到java.nio.file中,并继承接口:Watchable、Iterable<Path>、Comparble<Path>。Watchable接口描述了可以被监视是否发生变化的对象。

  Files类,对文件执行的许多操作都是由Files类中的静态方法提供的。要进行操作的文件是由文件的Path指定的。因此Files类的方法使用Path对象指定将要进行操作的文件。

  文件属性接口,与文件关联的是一套属性。这些属性包括文件的创建时间,最有一次修改时间,文件是否是目录以及文件的大小等。NIO将文件属性组织到几个接口中。属性是

  通过在java.nio,file.attribute包中定义的接口层次表示的。

流 API

  流是数据的渠道。代表了一个对象的序列。流操作数据源,如数组或集合。刘本身不存储数据,而只是移动数据,自移动过程中可能会对数据执行过滤,排序或其他操作。

流操作不修改数据源。

  Stream<T> T指定流中元素的类型。

  缩减操作,流提供的min()和max()方法基于流中元素返回记过,他们代表了缩减操作,因为每个操作都将一个流缩减为一个值。除了它们还提供了reduce()方法。通过

    reduce()方法,可以基于任意条件,从流中返回一个值。

    Obtional<T> reduce(BinaryOperator<T> accumulator) Optionalle包含了结果

    T reduce(T identityVal, BinaryOperator<T> accumulator) accumulator是一个操作两个值并得到结果的函数。identityVal,和流中任意元素的累计操作,得到的结果

                                                                                             就是元素本身,没有改变。BinaryOperator是一个函数式接口,扩展了BiFunction函数式接口。BinaryOperator

                            的apply():T apply(T val, U val2),在用到reduce()中时,val将包含前一个结果,val2将包含下一个元素在第一次

                            使用时,取决于所使用的reduce()版本,val将包含单位制或者第一个元素。

    <U> U reduce(U identityVal, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) combiner定义的函数将accumulator函数得到的两个值合并起来。

    需要理解的是,累加器操作必须满足一下按个约束:

    -无状态

    -不干预

    -结合性

    无状态以为这操作不依赖于任何状态信息。因此每个元素被单独处理。不干预是指操作不会改变数据源。最后,操作必须具有关联性。关联性使用的是其标准的数学含义。

    即,给定一个关联运算符,在一系列操作中使用该运算符时,先处理哪一个无关紧要。

  并行流,使用并行流有一点要记住:元素的顺序。流可以使有序的,也可以是无需的。如果数据源是有序的,那么流也是有序的。使用并行流的时候,有时候允许流是无序

    的可以获得性能上的提升。当并行流无序时,流的每个部分都可以被单独操作,不需要与其他部分协调。

    映射,将一个流的元素映射到另一个流。

    <R> Stream<R> map(Function<? super T, ? extends R> mapFunc)  R指定新流的元素类型,T指定调用流的元素类型。mapFunc是完成映射的Function实例。

    映射函数必须是无状态和不干预的。因为map()方法返回一个新流,所以它是中间方法。

    收集,有时候需要从流中获得集合。流API提供了collect()方法。它有两种形式:

    <R, A> R collect(Collector<? super T, A, R> collectorFunc) R指定结果的类型,T指定调用流的元素类型。内部累计类型由A指定。collectorFunc指定收集过程如何执行。

                              collecto()方法是一个终端方法。

    <R> R collect(Supplier<R> target, BiConsumer<R, ? super T> accumulator, BiConsumer <R, R> combiner) target指定如何创建用于保存结果的对象,如,要使用LinkedList

    作为结果集合,需要指定其构造函数。accumulator函数将一个元素添加到结果中,而combiner函数合并两个部分结果。他们都必须是无状态和不干预,并且具有关联性。

    target参数的类型是Supplier。它定义了get()方法。get()方法没有参数,在这里返回一个类型为R的对象。因此,在collect()方法中使用,get()方法返回一个指向可变存储

    对象的引用。accumulator和combiner类型是BiConsumer.BiConsumer是java.util.function包中定义的一个函数式接口。指定了抽象方法accept(): void accept(T obj, U obj2)

    

    Collectors类定义了许多可以直接使用的静态收集器方法。

  迭代器和流,虽然流不是数据存储对象,但是仍然可以使用迭代器来遍历其元素,就如同使用迭代器遍历集合中的元素一样。流API支持两类迭代器。一类是传统的Iterator

    一类是JDK8的Splitertor.

猜你喜欢

转载自www.cnblogs.com/jixp/p/10589082.html