Detailed java8 Stream API

table of Contents

A, Stream Flow Overview

Second, the way to create a Stream

Related API

Three, Stream intermediate operation

Screening and sliced     

Mapping

Sequence

Fourth, the operation is terminated

The first category API (too simple)

The second category AP

Reduction

collect


A, Stream Flow Overview

1, in java8 there are two most important change is the first Lambda expressions, the other is the Stream API.

2, Stream API truly functional programming style introduced to Java. This is by far, the best java class library in addition to, Stream API can greatly improve the productivity of java programmers, programmers to write efficient, clean, simple code.

3, Stream processing is a key abstractions java8 collection, you can specify that you want it to be a set of operations can be performed very complex search, filtering, mapping and database operations. Using the Operation Stream API over the collection is in the java level , similar to using a SQL database query execution, you can use Stream for parallel operation.

4. Why learn Stream API?

      The actual development, the project comes from many data sources Mysql, Oracle and other relational databases, but for MongDB, Redis and other non-relational database query out of the data needs to be processed in the java level.

5, Stream Collection and a set of differences:

      Deletions set change search operation is performed in the data structure (memory) level, the data source will change occurs;

      Stream operation is performed in the data (CPU) level, the data source does not change ensue.

6, illustrates a Stream

     

7, the Stream steps of: 

   (1) generating a stream (Stream),

            A data source, obtaining a flow;

   (2) an intermediate chain (pipelined) operation,

           An intermediate chain of operations, on the data source is processed;

   (3) generate a new stream,

           A termination operation, performing the intermediate operation chain, produce a result.

     Note: Stream operation is performed delayed, they will only need to wait until the results of the implementation.

 Second, the way to create a Stream

  • Related API

       

  • Specific Case
    public static void main(String[] args) {
            //1.Collection中的方法
            Collection<Integer> collection = new ArrayList<>();
            Stream<Integer> stream = collection.stream();
            Stream<Integer> stream1 = collection.parallelStream();
            //2.Arrays中的stream方法(静态方法,可直接调用)
            IntStream stream2 = Arrays.stream(new int[]{1, 2, 3});
            //3.Stream中的of方法(静态方法,可直接调用)
            Stream<String> stream3 = Stream.of("as", "cx1", "323");
            //4.Stream中的方法-创作无限流(结果有无限多个)
            /**
             * 4.1 iterate : 这里的例子可理解为,从2开始,每隔2产生一个数据,总共产生无穷多个
             * iterate的第二个参数是UnaryOperator,它是一个接口,继承内置函数型接口Function
             * public interface UnaryOperator<T> extends Function<T, T>
             *  此处使用Lambda表达式以及方法引用
             */
            Stream<Integer> stream4 = Stream.iterate(2, x -> x + 2);
            stream4.forEach(System.out::println);
            /**
             * 4.2 generate:
             * public static<T> Stream<T> generate(Supplier<T> s)
             * 参数是内置供给型接口Supplier
             * 此处使用Lambda表达式以及方法引用
             */
            Stream<Double> stream5 = Stream.generate(() -> Math.random());
            stream5.forEach(System.out::println);
        }

     

Three, Stream intermediate operation

Screening and sliced     

  • filter
  • Stream<T> filter(Predicate<? super T> predicate);
  • Receiving Lambda, exclude certain elements, to determine parameters is built Interface Predicate,
  • Of particular note is: "lazy loading" Stream operations or called "lazy loading": Only By termination, intermediate operations will be executed. Examples are verified.
public class FilterTest {
    private static List<Student> stuList;
    static {
        stuList = Arrays.asList(
                new Student(1, "zhangsan1", 12, 171.1, 3001D),
                new Student(2, "zhangsan1", 14, 172.1, 4001D),
                new Student(3, "zhangsan1", 16, 173.1, 5001D),
                new Student(4, "zhangsan1", 18, 174.1, 6001D),
                new Student(5, "zhangsan1", 20, 175.1, 7001D),
                new Student(6, "zhangsan1", 21, 176.1, 8001D),
                new Student(7, "zhangsan1", 22, 177.1, 9001D)
        );
    };
    @Test
    public void test01(){
        //1.创建Stream流
        Stream<Student> s1 = stuList.stream();
        //2.中间操作,找年龄大于18岁的学生
        Stream<Student> studentStream = s1.filter(x -> x.getAge() >= 18);
        //3.终止操作
        studentStream.forEach(x-> System.out.println(x.getAge()));
    }

    /**
     * 注意如果只执行1、2,不执行终止操作,则不会输出任何结果
     * 证明Stream操作的“延迟加载”或叫“惰性加载”:只有执行终止操作,中间操作才会被执行
     */
    @Test
    public void test02(){
        //1.创建Stream流
        Stream<Student> s1 = stuList.stream();
        //2.中间操作,找年龄大于18岁的学生
        Stream<Student> studentStream = s1.filter(x -> {
                System.out.println("正在执行过滤.......");
                return x.getAge() >= 18;
            }
         );
        //3.终止操作
        //studentStream.forEach(x-> System.out.println(x.getAge()));
    }

    /**
     * 链式操作
     */
    @Test
    public void test03(){
        stuList.stream()
        .filter(x -> x.getAge() >= 18)
        .forEach(x-> System.out.println(x.getAge()));
    }
}
  • limit
  • Stream<T> limit(long maxSize)
  • Flow cut off, so that it can not exceed a given number. The method of short-circuit, high efficiency.
    @Test
    public void test04(){
        stuList.stream()
                .limit(3)
                .forEach(System.out::println);
    }

 

  • skip
  • Stream<T> skip(long n)
  • Skip element, the flow returns to throw away the first n elements of the elements if the stream is less than n, an empty stream.
    @Test
    public void test04(){
        stuList.stream()
                .skip(3)
                .forEach(x->System.out.println(x.getName()));
    }

 

  • distinct
  • Stream<T> distinct()
  • Filter, and remove duplicate elements equals hashCode method according stream generated elements. So if you use a reference to the type, need to override hashCode and the equals .
  • Method overrides
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        return Objects.equals(getId(), student.getId()) &&
                Objects.equals(getName(), student.getName()) &&
                Objects.equals(getAge(), student.getAge()) &&
                Objects.equals(getHeight(), student.getHeight()) &&
                Objects.equals(getSalary(), student.getSalary());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName(), getAge(), getHeight(), getSalary());
    }
  • Specific Case
static {
        stuList = Arrays.asList(
                new Student(1, "zhangsan1", 12, 171.1, 3001D),
                new Student(1, "zhangsan1", 12, 171.1, 3001D),
                new Student(3, "zhangsan3", 16, 173.1, 5001D),
                new Student(4, "zhangsan4", 18, 174.1, 6001D),
                new Student(5, "zhangsan1", 20, 175.1, 7001D),
                new Student(6, "zhangsan6", 21, 176.1, 8001D),
                new Student(7, "zhangsan7", 22, 177.1, 9001D)
        );
}

@Test
public void test04(){
   stuList.stream()
          .distinct()
          .forEach(System.out::println);
}

 

Mapping

map: receiving Lambda, converting an element to extract information or other form. Receiving a parameter which is applied to each element, and maps it into a new element.

I understood to be popular mathematical function of the input x, x will be mapped into the corresponding y, x and return the original cover, so as to form new elements.

  • Case 1: The string becomes uppercase lowercase

       

  • Case 2: Get only the student's name

       

  •  Case 3: Get students older than 18 years old name

       

Sequence

  • sorted

Natural order: sorted according to the underlying internal comparator -> Conparable Interface -> comparaTo Method

  • Specifies the sorted ordering policy

Specify the sort strategy: to compare the underlying sorted according to external comparators -> Comparator Interface -> Be sure to specify the method to compare yourself to rewrite comparison rules.

Fourth, the operation is terminated

第一大类API(太过简单)

        

   

 第二大类AP

        用法大同小异,都不难。

        但,需要注意的是,一部分先查找后返回的API,采用的是Optional进行接收。因为查找的结果有可能是空集合。

        

具体实例:    

    

    

    

    

    

 

归约

终止操作中稍微有点难理解的的就是归约。

  • 归约:将流中的元素反复结合起来就行运算,得到一个值

                  T reduce(T identity,BinaryOption<T> accumulator)

  • 归约分析

       

  • 实例

       

 

收集

  • 收集:用于给Stream中的元素进行汇总。
  • <R,A> R collect(Collect<? super T,A,R> collector)

方法形参:Collector接口

方法实参:应是Collector接口的实例;如何获取:有一个Collector类,里面提供了各种方法,返回给我们Collector接口实例。

  • 收集的应用场景

(1)将代码放入指定的集合

  • Collectors.toList()

       

  • Collectors.toSet()

       

  • Collectors.toMap()

        由于Map集合结构的特殊性,这里需要注意 ,与以上两个不同的是,需要指定存储的key和value.

       

   (2)总数,平均值,总和,最大值,最小值(太过简单,不做过多描述)

       

       (3)分组(简单)

                

(4)分区:满足条件的在一个分区,不满足条件的在另一个分区(注意:总共只划分出两个分区)

                 

(5)连接:其实就是字符串拼接

                

 

发布了30 篇原创文章 · 获赞 7 · 访问量 1554

Guess you like

Origin blog.csdn.net/weixin_40391011/article/details/104045957