Java 8 new features stream programming

Stream summary and usage scenarios

Summary of stream

Stream is different from InputStream and outputStream. It is used to enhance the collection iterator to enable it to complete more efficient aggregation operations (filtering, sorting, statistical grouping), or large-scale data operations. In addition, with stream and lambada expressions The coding efficiency after the holiday is greatly improved, and the readability is stronger

Stream uses an intuitive way similar to querying data from a database using SQL statements to provide a high-level abstraction of Java set operations and expressions.

Before learning stream, you need to have a certain understanding of Lambda expressions.

The following example can explain what Stream can do:

[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-uDjczjF4-1599051678458)(/Users/faro_z/Library/Application Support/typora-user-images/image-20200902144322581 .png)]

In the above example, some colored plastic balls are obtained as the data source, and the red ones are first filtered out and melted into random triangles. Filter again and delete the small triangles. Finally, calculate the perimeter of the remaining graphics.

As shown in the figure above, for stream processing, there are mainly three key operations: stream creation, intermediate operation, and terminal operation.

In more concise terms, it is to put the elements in the collection on the assembly line , and add conditions at each step , filter some elements , and finally leave the elements you want.

Stream operation process

For stream processing, there are mainly three key operations: stream creation, intermediate operation, and terminal operation.

  • Stream creation: is the stream() method
  • Intermediate operations: filtering and sorting operations
  • Final operation: take out and print these operations

The following will give a specific introduction to these three types of operations

Pipeline source/stream creation

Switching Collection to pipeline source is simple, call stream

heros.stream();

But the array does not have a stream method, you need to use

Arrays.stream(hs);

or

Stream.of(hs);

Don't confuse InputStream and OutputStream in I/O operations here. The two are not the same concept.

Intermediate operation

Each intermediate operation will return a Stream. For example, .filter() will return a Stream. The intermediate operation is a "lazy" operation and will not be traversed.
There are many intermediate operations, mainly divided into two categories
, filtering elements and converting them into other forms of flow

Filter elements:

filter matches
distinct to remove duplicates (judging by equals) //Note: equals in Object judges whether it is the same object, the following is the source code of equals() in Object:

public boolean equals(Object obj)
{
     
     
	return this == obj;
}

But equals in String judges whether the string content is the same (of course, if it is the same string object, it will return true)

sorted Natural sort
sorted(Comparator) Specify sort
limit, keep
skip and ignore

Convert to other forms of stream:

mapToDouble converted to double stream
similar to mapToInt(), mapToLong()

map is converted to any type of stream

package lambda;
  
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
import charactor.Hero;
  
public class TestAggregate {
    
    
  
    public static void main(String[] args) {
    
    
        Random r = new Random();
        List<Hero> heros = new ArrayList<Hero>();
        for (int i = 0; i < 5; i++) {
    
    
            heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
        }
        //制造一个重复数据
        heros.add(heros.get(0));
        System.out.println("初始化集合后的数据 (最后一个数据重复):");
        System.out.println(heros);
        System.out.println("满足条件hp>100&&damage<50的数据");
          
        heros
            .stream()
            .filter(h->h.hp>100&&h.damage<50)
            .forEach(h->System.out.print(h));
          
        System.out.println("去除重复的数据,去除标准是看equals");
        heros
            .stream()
            .distinct()
            .forEach(h->System.out.print(h));
        System.out.println("按照血量排序");
        heros
            .stream()
            .sorted((h1,h2)->h1.hp>=h2.hp?1:-1)
            .forEach(h->System.out.print(h));
          
        System.out.println("保留3个");
        heros
            .stream()
            .limit(3)
            .forEach(h->System.out.print(h));
          
        System.out.println("忽略前3个");
        heros
            .stream()
            .skip(3)
            .forEach(h->System.out.print(h));
          
        System.out.println("转换为double的Stream");
        heros
            .stream()
          //这里虽然获取的是血量
          //但是操作的还是对象
            .mapToDouble(Hero::getHp)
            .forEach(h->System.out.println(h));
          
        System.out.println("转换任意类型的Stream");
        heros
            .stream()
            .map((h)-> h.name + " - " + h.hp + " - " + h.damage)
            .forEach(h->System.out.println(h));
          
    }
}

[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-acom9UEy-1599051678462)(/Users/faro_z/Library/Application Support/typora-user-images/image-20200902191427499 .png)]

Look at another example

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
Stream s = strings.stream()
  .filter(string -> string.length()<= 6)
  .map(String::length)
  .sorted()
  .limit(3)
  .distinct();

The following figure shows the change process of the Stream object

[External link image transfer failed. The origin site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-JPggVXPb-1599051678467)(/Users/faro_z/Library/Application Support/typora-user-images/image-20200902193853184 .png)]

Final operation

The result of the intermediate operation of Stream is still a Stream, so how to convert a Stream to the type we need? For example, calculating the number of elements in the stream, replacing the stream with a set, and so on. This requires terminal operation

The final operation consumes the stream and produces a final result. In other words, after the final operation, the stream cannot be used again, nor can any intermediate operations be used, otherwise an exception will be thrown.
Common ending operations are as follows:

forEach() traverses each element
collect()
toArray() is converted to an array
min(Comparator) takes the smallest element
max(Comparator) takes the largest element
count() is used to count the number of elements in the stream
findFirst() the first element

The following is an example of using collect

List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis");
strings  = strings
  .stream()
  .filter(string -> string.startsWith("Hollis"))
  .collect(Collectors.toList());
//找出以“Hollis”开头的元素
System.out.println(strings);
//Hollis, HollisChuang, Hollis666, Hollis

to sum up

Stream in Java is like a database query function, which can help us write more efficient code

Guess you like

Origin blog.csdn.net/weixin_44062380/article/details/108370326