资讯专栏INFORMATION COLUMN

Stream流与Lambda表达式(五) Stream BaseStream AutoClose

HitenDev / 1680人阅读

摘要:陈杨一流的定义流支持串行并行聚合操作元素序列二流的创建流的创建以方法生成流三

package com.java.design.java8.Stream.StreamDetail;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

/**
 * @author 陈杨
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class StreamDetail {

    private List integerList;

    @Before
    public void init() {
        integerList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
    }

    @Test
    public void testStreamDetail() {
一、流的定义
        //    Stream :  A sequence of elements supporting sequential and parallel aggregate operations.
        //    流: 支持 串行、并行 聚合操作 元素序列
二、流的创建
        //    流的创建:
        //    Collection.stream()  Collection.parallelStream()
        //    Stream.generate
        System.out.println("-----------------------------------------
");
        System.out.println("以Stream.generate方法生成流");
        Stream generate = Stream.generate(UUID.randomUUID()::toString);
        generate.findFirst().ifPresent(System.out::println);
        System.out.println("-----------------------------------------
");
三、对象引用流
        //    对象引用流
        //    Stream , which is a stream of object references
四、流的计算
        //    流的计算:    stream pipeline
        //    To perform a computation, stream operations are composed into a  stream pipeline.
五、流管道组成
        //    流管道组成:  源数据source-->数组、集合、生成器函数、IO通道等
        //                 [0,n) 中间操作(intermediate operations) 一个流转换 为 另一个新流
        //                 终止操作(terminal operation)产生一个结果 或有副作用(修改流中元素 属性或状态)
        //    A stream pipeline consists of a source (which  might be an array,
        //    a collection, a generator function, an I/O channel,etc),
        //    zero or more intermediate operations (which transform a
        //    stream into another stream, such as {@link Stream#filter(Predicate)}), and a
        //    terminal operation (which produces a result or side-effect, such
        //    as {@link Stream#count()} or {@link Stream#forEach(Consumer)}).
六、流的消费
        //    流的消费:  流中对于源数据的计算 有且仅有在终止操作触发时才会被调用
        //               流中元素只有在被需要时才会被消费
        //               lazy(惰性): 如果没有终止操作 那么一系列的中间操作都不会被执行
        //               stream流操作只会执行一次: stream中有一个容器 将所有中间操作打包 放入容器中
        //               调用终止操作时 触发容器的链式中间操作 将流中每一个元素 应用于中间业务逻辑
        //    Streams are lazy; computation on the source data is only performed when the
        //    terminal operation is initiated, and source elements are consumed only as needed.
        //    流创建后 只能被消费一次 否则抛异常
        //    除非流被设计成为显示并发修改的流如ConcurrentHashMap 否则未期望或错误的行为就会在执行时产生
        //    Unless the source was explicitly designed for concurrent modification
        //    (such as a ConcurrentHashMap),unpredictable or erroneous behavior may result
        //    from modifying the stream source while it is being queried.
        //    java.lang.IllegalStateException: stream has already been operated upon or closed
七、 Lambda表达式的正确行为
        //    Lambda表达式的正确行为:
        //    To preserve correct behavior,these behavioral parameters:

        //    must be non-interfering
        //    (they do not modify the stream source);

        //    in most cases must be stateless
        //    (their result should not depend on any state that might change during execution
        //    of the stream pipeline).
八、流与集合
//    流与集合:
//    集合关注的是对元素的管理与访问
//    流不会直接提供直接访问或操作其元素的方法
//    流提供声明性描述: 源 与 建立于源之上的聚合计算执行操作
//    如果流没有提供预期的功能 可执行受控遍历(iterator、spliterator)
//    Collections and streams, while bearing some superficial similarities,
//    have different goals.  Collections are primarily concerned with the efficient
//    management of, and access to, their elements.  By contrast, streams do not
//    provide a means to directly access or manipulate their elements, and are
//    instead concerned with declaratively describing their source and the
//    computational operations which will be performed in aggregate on that source.
//    However, if the provided stream operations do not offer the desired
//    functionality, the {@link #iterator()} and {@link #spliterator()} operations
//    can be used to perform a controlled traversal.
九、 流的MapReduce操作
//   流的MapReduce操作  求集合 每个元素的2倍 之和
//   此例中:Integer 每执行一次reduce操作 触发 该元素的map操作一次
System.out.println(integerList.stream().map(i -> 2 * i).reduce(0, Integer::sum));
System.out.println("-----------------------------------------
");
十、流资源自动关闭 AutoCloseable接口实现
package com.java.design.java8.Stream.StreamDetail;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author 陈杨
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class AutoCloseableTest implements AutoCloseable {

    /*
     *      An object that may hold resources (such as file or socket handles)
     *      until it is closed. The {@link #close()} method of an {@code AutoCloseable}
     *      object is called automatically when exiting a {@code
     *      try}-with-resources block for which the object has been declared in
     *      the resource specification header. This construction ensures prompt
     *      release, avoiding resource exhaustion exceptions and errors that
     *      may otherwise occur.
     *
     *      实现AutoCloseable接口:
     *          使用try--with--resources 代码块 替代 try--catch--finally
     *          在代码块运行完毕后 自动实现 资源的关闭
     *      public interface AutoCloseable {
     *               void close() throws Exception;
     *                }
     */

    public void doSomeThing() {

        System.out.println("method doSomeThing invoked!");
    }


    @Override
    public void close() throws Exception {
        System.out.println("method close invoked!");
    }


    @Test
    public void testAutoCloseable() throws Exception {

        try (AutoCloseableTest autoCloseableTest = new AutoCloseableTest()) {
            autoCloseableTest.doSomeThing();
        }
    }


}
十一、认识BaseStream 与 closeHandler
package com.java.design.java8.Stream.StreamDetail.BaseStreamDetail;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author 陈杨
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class BaseStreamDetail {

    private List list;
    private NullPointerException myException;

    @Before
    public void init() {
        list = Arrays.asList("Kirito", "Asuna", "Illyasviel", "Sakura");
        myException = new NullPointerException("my NullPointerException");
    }

    @Test
    public void testBaseStreamDetail() {

        // public interface Stream extends BaseStream>

      /*public interface BaseStream> extends AutoCloseable {

         Iterator iterator();

       * Returns a spliterator for the elements of this stream.

         Spliterator spliterator();


       *  当终止操作应用于流时 判断其是否并行
       *  当执行终止操作之后 执行isParallel() 会得到不可预期的结果
       *    此方法需适用于终止操作之前
       *
       * Returns whether this stream, if a terminal operation were to be executed,
       * would execute in parallel.  Calling this method after invoking an
       * terminal stream operation method may yield unpredictable results.
       *
           boolean isParallel();


       * 返回一个等价的串行流
       *     流本身已经是串行 或 流的状态已被修改为串行
       *
       * Returns an equivalent stream that is sequential.  May return
       * itself, either because the stream was already sequential, or because
       * the underlying stream state was modified to be sequential.
       *
        S sequential();


       * 返回一个等价的并行流
       *     流本身已经是并行 或 流的状态已被修改为并行
       *
       * Returns an equivalent stream that is parallel.  May return
       * itself, either because the stream was already parallel, or because
       * the underlying stream state was modified to be parallel.
       *
          S parallel();


       * 返回一个等价的无序流
       *     流本身已经是无序 或 流的状态已被修改为无序
       *
       * Returns an equivalent stream that is
       * unordered.  May return
       * itself, either because the stream was already unordered, or because
       * the underlying stream state was modified to be unordered.
       *
          S unordered();


       * 返回一个等价的流 有close handler
       *     close handler当流close()方法调用时触发
       *     调用顺序:close handlers被添加先后顺序
       *
       *     所有的close handlers都会被调用 即使出现了异常
       *     如果任意close handler抛出异常
       *             那么第一个异常会传递给调用段
       *             其他异常(剩余或被抑制)会传递给调用段
       *                     除非其中有与第一个异常相同的异常(相同对象)  因为相同异常不能抑制自身
       *
       * Returns an equivalent stream with an additional close handler.  Close
       * handlers are run when the {@link #close()} method
       * is called on the stream, and are executed in the order they were
       * added.  All close handlers are run, even if earlier close handlers throw
       * exceptions.  If any close handler throws an exception, the first
       * exception thrown will be relayed to the caller of {@code close()}, with
       * any remaining exceptions added to that exception as suppressed exceptions
       * (unless one of the remaining exceptions is the same exception as the
       * first exception, since an exception cannot suppress itself.)  May
       * return itself.
       *
       * @param closeHandler A task to execute when the stream is closed
       * @return a stream with a handler that is run if the stream is closed

          S onClose(Runnable closeHandler);


       * 关闭流 调用流管道中的close handlers
       *
       * Closes this stream, causing all close handlers for this stream pipeline  to be called.

          @Override
          void close();
      }*/


        try (Stream stream = list.stream()) {
            stream.onClose(() -> {
                System.out.println("close handler first");
                // throw new NullPointerException("null pointer exception 1");
                throw myException;
            }).onClose(() -> {
                System.out.println("close handler second");
                // throw new NullPointerException("null pointer exception 2");
                throw myException;
            }).onClose(() -> {
                System.out.println("close handler third");
                // throw new NullPointerException("null pointer exception 3");
                throw myException;
            }).forEach(System.out::println);
        }


    }


}
十二、测试结果
testStreamDetail测试
  .   ____          _            __ _ _
 / / ___"_ __ _ _(_)_ __  __ _    
( ( )\___ | "_ | "_| | "_ / _` |    
 /  ___)| |_)| | | | | || (_| |  ) ) ) )
  "  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-20 17:40:31.060  INFO 15872 --- [           main] c.j.d.j.S.StreamDetail.StreamDetail      : Starting StreamDetail on DESKTOP-87RMBG4 with PID 15872 (started by 46250 in E:IdeaProjectsdesign)
2019-02-20 17:40:31.062  INFO 15872 --- [           main] c.j.d.j.S.StreamDetail.StreamDetail      : No active profile set, falling back to default profiles: default
2019-02-20 17:40:31.584  INFO 15872 --- [           main] c.j.d.j.S.StreamDetail.StreamDetail      : Started StreamDetail in 0.728 seconds (JVM running for 1.461)
-----------------------------------------

以Stream.generate方法生成流
2742c0e9-7bdb-4c7e-88c9-b5d94684215c
-----------------------------------------

90
-----------------------------------------
AutoCloseableTest测试
  .   ____          _            __ _ _
 / / ___"_ __ _ _(_)_ __  __ _    
( ( )\___ | "_ | "_| | "_ / _` |    
 /  ___)| |_)| | | | | || (_| |  ) ) ) )
  "  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-20 17:39:45.456  INFO 16320 --- [           main] c.j.d.j.S.S.AutoCloseableTest            : Starting AutoCloseableTest on DESKTOP-87RMBG4 with PID 16320 (started by 46250 in E:IdeaProjectsdesign)
2019-02-20 17:39:45.457  INFO 16320 --- [           main] c.j.d.j.S.S.AutoCloseableTest            : No active profile set, falling back to default profiles: default
2019-02-20 17:39:45.956  INFO 16320 --- [           main] c.j.d.j.S.S.AutoCloseableTest            : Started AutoCloseableTest in 0.716 seconds (JVM running for 1.433)
method doSomeThing invoked!
method close invoked!
testBaseStreamDetail测试
  .   ____          _            __ _ _
 / / ___"_ __ _ _(_)_ __  __ _    
( ( )\___ | "_ | "_| | "_ / _` |    
 /  ___)| |_)| | | | | || (_| |  ) ) ) )
  "  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-20 17:46:41.886  INFO 15216 --- [           main] c.j.d.j.S.S.B.BaseStreamDetail           : Starting BaseStreamDetail on DESKTOP-87RMBG4 with PID 15216 (started by 46250 in E:IdeaProjectsdesign)
2019-02-20 17:46:41.887  INFO 15216 --- [           main] c.j.d.j.S.S.B.BaseStreamDetail           : No active profile set, falling back to default profiles: default
2019-02-20 17:46:42.435  INFO 15216 --- [           main] c.j.d.j.S.S.B.BaseStreamDetail           : Started BaseStreamDetail in 0.762 seconds (JVM running for 1.48)
Kirito
Asuna
Illyasviel
Sakura
close handler first
close handler second
close handler third

java.lang.NullPointerException: my NullPointerException

Process finished with exit code -1


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73346.html

相关文章

  • Stream流与Lambda达式(一) 杂谈

    摘要:一流转换为数组集合陈杨将流转换为数组将流转换为数组将流转换为集合将流转换为集合解析 一、流 转换为数组、集合 package com.java.design.java8.Stream; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context...

    Harpsichord1207 评论0 收藏0
  • Stream流与Lambda达式(六) SpliteratorDetail

    摘要:陈杨一流的创建源集合一流的创建源集合集合默认方法接口与静态类实现接口与静态类实现二接口二接口接口对数据源中元素进行遍历或分区延迟绑定数据源绑定时机首次遍历切分查询大小而不是在创建时非延迟绑定数据源绑定时机创建时或的方法首次调用与 package com.java.design.java8.Stream.StreamDetail.BaseStreamDetail; import or...

    cjie 评论0 收藏0
  • Stream流与Lambda达式(三) 静态工厂类Collectors

    摘要:陈杨一静态工厂类实现方式一静态工厂类实现方式静态工厂类最终由实现通过实现通过实现底层由实现是的一种具化表现形式使用拼接字符串二静态工厂类常用收集器二静态工厂类常用收集器返回一个不可修改的按照相遇的顺序返回一个不可修改的无序返回 /** * @author 陈杨 */ @SpringBootTest @RunWith(SpringRunner.class) public class...

    phodal 评论0 收藏0
  • Stream流与Lambda达式(四) 自定义收集器

    摘要:一自定义收集器陈杨将集合转换为集合存放相同元素二自定义收集器陈杨将学生对象按照存放从中间容器数据类型转换为结果类型数据类型一致若不一致抛出类型转换异常对中间容器数据结果类型进行强制类型转换多个线程同时操作同一个容器并行多线 一、自定义SetCustomCollector收集器 package com.java.design.Stream.CustomCollector; impor...

    wind5o 评论0 收藏0
  • Stream流与Lambda达式(二) Stream收集器 Collector接口

    摘要:一收集器接口陈杨收集器接口汇聚操作的元素类型即流中元素类型汇聚操作的可变累积类型汇聚操作的结果类型接口一种可变汇聚操作将输入元素累积到可变结果容器中在处理完所有输入元素后可以选择将累积的结果转换为最终表示可选操作归约操作 一、Stream收集器 Collector接口 package com.java.design.java8.Stream; import com.java.desi...

    or0fun 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<