Java - Detailed explanation of Stream flow

Article directory


foreword

Hello everyone, long time no see. Recently, due to the influence of practical training, the update has been delayed. In this update, it is estimated that javaSE is basically finished, and there are still some things that are left behind that will be added later. The next time we meet is the data structure.

Let's look forward to it! Then let us step into the study of Stream! 

 


1. What is Stream?

Stream stream is a new feature in Java 8, which provides a way to deal with collections and arrays. Stream allows us to process data in a more concise, efficient, and more readable way. Stream flow can be used for filtering, mapping, sorting, aggregation and other operations, which allows us to avoid using loops and conditional statements to process data, thus making the code more concise and easy to understand. Stream operations can be divided into two types: intermediate operations and termination operations. The intermediate operations return a new Stream, and the termination operations return a non-Stream type result. The processing of the Stream stream is evaluated lazily, and the data will only be processed when the termination operation is performed.

Stream (Stream) is a sequence of elements based on a data source that supports one-time processing of data , and the stream can only be used once.

The original intention of stream design is to support functional programming. Its purpose is to separate data processing and data storage, making data processing more flexible and efficient. Therefore, the elements of the stream are only temporary data passed in the stream, they are not permanently stored in memory. When the stream's elements are consumed, they are freed and cannot be used again.

If you need to perform multiple different operations on the same data set, you can use the intermediate operation method of the stream to build multiple stream pipelines, each of which can perform different operations on the stream and return a new stream . This allows multiple operations on the same dataset without re-fetching the dataset.

2. Stream Classification

sequence flow

A sequential stream is a single-threaded stream that processes each element sequentially in the order of the data stream, and the processing of each element must wait for the processing of the previous element to complete before it can begin.

parallel stream

A parallel stream is a multi-threaded stream that divides data into multiple parts for parallel processing, and each part can be processed in a different thread to improve processing efficiency.

Using sequential streams can ensure the order and consistency of data processing, and is suitable for processing small amounts of data. The use of parallel streams can improve the speed of data processing, which is suitable for situations where the amount of data is large and the processing time is long. But parallel streams also have some disadvantages, such as additional overhead for communication and synchronization between threads, and parallel streams may affect the order and consistency of data. Therefore, you need to pay attention to issues such as thread safety and data consistency when using parallel streams.

the difference

The difference between sequential streams and parallel streams is that they are processed differently, sequential streams are single-threaded, while parallel streams are multi-threaded. There are also some differences in the methods used, for example:

  1. Obtaining sequence stream: You can use the stream() method of the collection class, the stream() method of the Arrays class, the of() method of the Stream class, the iterate() method of the Stream class, the generate() method of the Stream class, and the lines of the Files class () method, etc. to get the sequence flow.

  2. Obtaining parallel streams: You can use the parallelStream() method of the collection class, the parallel() method of the of() method of the Stream class, the parallel() method of the iterate() method of the Stream class, and the parallel() method of the generate() method of the Stream class. ) method etc. to get parallel streams.

In addition, the usage methods of sequential streams and parallel streams are basically the same . For example, methods such as map(), filter(), and reduce() can be used to operate streams. However, it should be noted that issues such as thread safety and data consistency need to be considered when using parallel streams.

Below I will only explain the use of sequential streams in detail. The use of parallel streams is not bad. If you are interested, you can try it yourself.

3. Common ways to obtain streams

As mentioned earlier, a stream is a sequence of elements based on a data source that supports one-time processing of data , and the stream can only be used once

So it doesn't make any sense to save the stream, but it is still necessary to obtain it. Below I will explain the commonly used methods in detail, and the methods that are not commonly used will also be given. If you are interested, you can try it yourself!

By the way, I think it is necessary because I don’t have a wide range of knowledge now, and I don’t have access to too complicated content. I will make up for it when I become a master

Haha, in fact, most of the things I don’t say are because I don’t know how to do it, Xiao Heizi, the chicken feet are leaking, right?

1. Get the stream through the collection: You can use the stream() method or the parallelStream() method in the collection class to get the stream

2. Get the stream through the array: You can use the stream() method in the Arrays class to get the stream.

3. Obtain the stream through the Stream.of() method: You can use the of() method in the Stream class to obtain the stream.

4. Obtain the stream through the Stream.iterate() method: You can use the iterate() method in the Stream class to obtain the stream

Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5); // get sequence stream

5. Get the stream through the Stream.generate() method: You can use the generate() method in the Stream class to get the stream

Stream<Double> stream = Stream.generate(Math::random).limit(5); // get sequence stream

 6. Obtain the stream through the Files.lines() method: You can use the lines() method in the Files class to obtain the stream.

Stream<String> stream = Files.lines(Paths.get("file.txt")); // get sequence stream

1. Get the stream through the collection

 Variable parameters do not understand see http://t.csdn.cn/SSp8u for details

 source code

 

 Just looked at it, it's a bit troublesome, I owe it first

For the time being, everyone knows how to get it.

2. Get the stream through the array

 source code

3. Obtain the stream through the Stream.of() method

 

Four. Common method usage

  1. filter(Predicate<T> predicate): Filter the elements in the stream, and only keep the elements that meet the conditions.
  2. map(Function<T, R> mapper): Map the elements in the stream according to the specified method, and return a new stream.
  3. flatMap(Function<T, Stream<R>> mapper): Map the elements in the stream according to the specified method, and then combine all the mapping results into a stream.
  4. limit(long maxSize): Intercepts the first maxSize elements in the stream.
  5. skip(long n): Skip the first n elements in the stream.
  6. sorted(): Sorts the elements in the stream.
  7. distinct(): Deduplication, removes duplicate elements in the stream.
  8. forEach(Consumer<T> action): Performs the specified action on each element in the stream.
  9. reduce(T identity, BinaryOperator<T> accumulator): Accumulates the elements in the stream according to the specified method, and returns an Optional object.
  10. collect(Collector<T, A, R> collector): Collect the elements in the stream into a collection.
  11. concat merges two streams a and b into one stream

The ones marked in red will not be explained, some are beyond my ability, of course there are two, haha, mainly because I am lazy and don’t want to understand

It is worth mentioning that the sixth sorting seems to be able to specify the sorting rules, I will try it

indeed

If you are interested, you can try it. I have already explained the sorting in my previous blog post very thoroughly, so I won’t repeat it here.

Below I will only give a brief demonstration. If you want to master it, you can practice it. At the end, I will attach practice questions and answers

1.filter(Predicate<T> predicate): filter the elements in the stream, and only keep the elements that meet the conditions

2.limit  &&  skip

 3.distinct(): Deduplication, remove repeated elements in the stream.

 4. concat merges the two streams a and b into one stream

5. map(Function<T, R> mapper): Map the elements in the stream according to the specified method, and return a new stream

 Suddenly thought of this question, please explain

 6.forEach(Consumer<T> action): Perform the specified operation on each element in the stream.

 For now, what I use the most is to traverse

Everyone just needs to master the traversal

7. collect(Collector<T, A, R> collector): Collect the elements in the stream into a collection.

 

 5. Practice

0, filter odd numbers, leaving only even numbers 

ArrayList<Integer> list = new ArrayList<>(); 
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10); 

1 , Actors only need to be the first two people whose names are 3 characters 
2, actresses only need to have the surname Yang, and don’t want the first 
3, merge the filtered actor’s name and actress name together 
4, combine the actor in the previous step Information is encapsulated into Actor objects. 
5. Save all actor objects to the List collection. 

Remarks: actor class Actor, the attributes are: name, age 
Actors: "Cai Kunkun,24", "Ye Yuxian,23", "Liu Butian,22", "Wu Zhi,24", "Gu Jia,30" , "Xiao Liangliang,27" 
actresses: "Zhao Xiaoying,35", "Yang Ying,36", "Gao Yuanyuan,43", "Zhang Tiantian,31", "Liu Shi,35", "Yang Xiaomi,33"
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();

        Collections.addAll(list1,"蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");
        Collections.addAll(list2,"赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");

        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);

        // 0, 过滤奇数,只留下偶数

        List<Integer> collect = list.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toList());

        System.out.println(collect);

        // 1,男演员只要名字为3个字的前两人

        Stream<String> stream1 = list1.stream().filter(s -> s.split(",")[0].length() == 3).limit(2);

        //  2,女演员只要姓杨的,并且不要第一个

        Stream<String> stream2 = list2.stream().filter(s -> s.startsWith("杨")).skip(1);

        // 3,把过滤后的男演员姓名和女演员姓名合并到一起

        //Stream.concat(stream1,stream2).forEach(s-> System.out.println(s));

        // 4,将上一步的演员信息封装成Actor 对象

        // 类型转换 String-> Actor
        Stream.concat(stream1, stream2).map(new Function<String, Actor>() {
            @Override
            public Actor apply(String s) {
                Actor actor = new Actor();

                actor.setName(s.split(",")[0]);

                actor.setAge(Integer.parseInt(s.split(",")[1]));

                return actor;
            }
        }).forEach(s-> System.out.println(s.getName()+" "+s.getAge()));

        // 5,将所有的演员对象都保存到List集合中。
        List<Actor> list3 = Stream.concat(stream1, stream2).map(s -> new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());

        System.out.println(list3);

Summarize

That's all for today, everyone remember to do exercises

 

Guess you like

Origin blog.csdn.net/weixin_73869209/article/details/130850722