Stream stream, method reference

A Stream stream

Stream can easily think of I/O Stream, but in fact, who stipulates that a stream must be an IO stream? In Java 8, thanks to Lambda's functional programming, a new Stream concept was introduced to address the drawbacks of existing collection class libraries.

The downside of loop traversal Java 8 Lambda allows us to focus more on What to do than How to do it.

The syntax for a for loop is "how to"

What is the loop of the for loop?

Traverse refers to a cycle in which each element is processed one by one, not the first through the last. The former is the purpose, the latter is the way.

Better writing for Stream streams:

import java.util.ArrayList;
import java.util.List;
public class Demo03StreamFilter {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Zhang Wuji");
list.add("Zhou Zhiruo");
list.add("Zhao Min");
list.add("Zhang Qiang");
list.add("Zhang Sanfen");
list.stream()
.filter(s ‐> s.startsWith("Zhang"))
.filter(s ‐> s.length() == 3)
.forEach(System.out::println);
}
}

1.1 Streaming Thought Overview

filter, map, skip all operate on function models, and collection elements are not actually processed. The entire model will operate according to the specified policy only if the end method count is executed. This is due to the delayed execution feature of Lambda.

Stream is an element queue from a data source

1. Elements are objects of a particular type that form a queue. Stream in Java does not store elements, it calculates on demand.

2. Sources of data sources and streams. It can be a collection, an array, etc.

3. Unlike previous Collection operations, Stream operations have two basic features:

Pipelining: Intermediate operations return the stream object itself. This allows multiple operations to be concatenated into a single pipe, like a fluentstyle. This can optimize operations such as laziness and shortcircuiting.

Internal Iteration: Collection traversal used to be explicit outside the collection via Iterator or enhanced for, which is called external iteration. Stream provides a way to iterate internally, and streams can call traversal methods directly.

1.2 Get Stream

java.util.Stream is the most commonly used stream interface added by java 8. (This is not a functional interface.)

Getting a stream is very simple, and there are several common ways to do this:

- All Collection collections can obtain streams through the stream default method;

default Stream<E> stream ()

The static method of -Stream interface ofcan get the stream corresponding to the array.

static <T> Stream <T> of (T...values)

A parameter is a variable parameter, so we can pass an array

Java. Util. The Map interface is not a subinterface of Collection, and its K-V data structure does not conform to the single characteristics of stream elements, so getting the corresponding stream requires sub-key s, value s, entries, and so on:

java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class Demo05GetStream {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
// ...
Stream<String> keyStream = map.keySet().stream();
Stream<String> valueStream = map.values().stream();
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
}
}

Get streams from arrays. If you are using arrays instead of collections or maps, since it is not possible to add default methods to array objects, the Stream interface provides a static method of, which is easy to use

import java.util.stream.Stream;
public class Demo06GetStream {
public static void main(String[] args) {
String[] array = { "Zhang Wuji", "Zhang Cuishan", "Zhang Sanfen", "Zhang Yiyuan" };
Stream<String> stream = Stream.of(array);
}
}

Stream flow is a pipe flow and can only be consumed (used) once

When the first Stream stream calls the method, the data goes to the next Stream, and then the first Stream stream is used and closed. The first stream can no longer call methods.

1.3 Stream Stream Common Methods

1.3.1 map

Converting one data type to another is called mapping. R apply (T t)

import java.util.stream.Stream;
public class Demo08StreamMap {
public static void main(String[] args) {
//Create a Stream stream
Stream<String> stream = Stream.of("1", "2", "3");
Stream<Integer> stream2 = stream.map(str‐>Integer.parseInt(str));
}
}Number

1.3.2 Statistics: count

As with the size method in the old Collection collection, streams provide count methods to count the number of elements: long count();

This is a termination method. The return value is an integer of Lang type and cannot continue to call other methods in Stream.

1.3.3 limt method

Used to intercept elements in a stream. The limit method intercepts streams using only the first n, and the method signature is Stream<T> limit (Long maxSize); The parameter is of Long type and is intercepted without operation if the current length of the collection is greater than the parameter. The limit method is a deferred method, but intercepting elements in the stream returns a new stream

import java.util.stream.Stream;
public class Demo10StreamLimit {
public static void main(String[] args) {
Stream<String> original = Stream.of("Zhang Wuji", "Zhang Sanfen", "Zhou Zhiruo");
Stream<String> result = original.limit(2);
System.out.println(result.count()); // 2
}
}

1.3.4 skip

If you want to skip the first few elements, you can use the skip method to get a new stream after interception: Stream<T> skip(long n); If the current length of the stream is greater than n, the first n are skipped; Otherwise, you will get an empty stream of length 0.

import java.util.stream.Stream;
public class Demo11StreamSkip {
public static void main(String[] args) {
//Get a Strem Stream
Stream<String> original = Stream.of("Pleasant Sheep", "Lazy sheep", "Goat","Grey Wolf", "Red Wolf");
//Skip the first three elements using the skip method
Stream<String> result = original.skip(2);
System.out.println(result.count()); // 1
}
}

Combination 1.3.5: concat

If you have two streams that you want to merge into one, you can use the static method concat:static <T> Stream<T> concat (Stream<? Extends T> a, Stream<? Extends T> b) of the Stream interface.

Note: This is a static method, with java. The concat method in lang.String is different.

import java.util.stream.Stream;
public class Demo12StreamConcat {
public static void main(String[] args) {
Stream<String> streamA = Stream.of("Zhang Wuji");
Stream<String> streamB = Stream.of("Zhang Cuishan");
Stream<String> result = Stream.concat(streamA, streamB);
}
}

1.4 Exercises

/*  subject
 There are now two ArrayList collection storage queues with multiple member names, requiring the use of traditional for loops (or enhanced for loops) in turn to
 The following steps:
1. The first team only needs the name of a member with three words; Store in a new collection.
2. Only the first three people will be selected after the first team is screened. Store in a new collection.
3. The second team only needs the names of the members of Zhang; Store in a new collection.
4. Do not use the first two people after the second team has been screened; Store in a new collection.
5. Merge the two teams into one team; Store in a new collection.
6. Create a Person object by name; Store in a new collection.
7. Print Person object information for the entire team.
*/
public class DemoStream {
public static void main(String[] args) {
    //First Team
    ArrayList<String> one = new ArrayList<>();
    one.add("Dili Reba");
    one.add("Song Yuan Qiao");
    one.add("Su Bingtian");
    one.add("King of Kings");
    one.add("Lau Andy");
    one.add("Lao Zi");
    one.add("Zhuang Zi");
    one.add("Guo Fucheng");
    //The first team is stored in a new set as long as the name is a three-word circular name
    ArrayList<String> one1 = new ArrayList<>();
    for (String s:one)
          {
              if (s.length()==3){
                  one1.add(s);
              }
          }
    ArrayList<String> one2 = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        one2.add(one1.get(i));
    }

    //Second Team
    ArrayList<String> two = new ArrayList<>();
    two.add("Gulinaza");
    two.add("Zhang Wuji");
    two.add("Zhao Liying");
    two.add("Zhang Sanfen");
    two.add("Nicholas");
    two.add("Zhang Tian Ai");
    two.add("Zhang sufficiently large");
    //The second team stores the names of only the members of the first team in the new collection
    ArrayList<String> two1 = new ArrayList<>();
    for (String s:two) {
    if(s.startsWith("Zhang"))   {
        two1.add(s);
    }
    }
    //4. Do not store the first two people in a new collection after the second team has been filtered.

ArrayList<String> two2 = new ArrayList<>();
    for (int i = 2; i <two1.size(); i++) {
        two2.add(two1.get(i));
    }
    //Merge two teams into one team and store in a new collection

    ArrayList<String> all = new ArrayList<>();
    all.addAll(one2);
    all.addAll(two2);
    //6 Create a Person object by name and store it in a new collection.
    ArrayList<Person>  list = new ArrayList<>();
    for (String name:all)
    {
     list.add(new Person(name));
    }
   //Print every Person
    for (Person p:list) {
        System.out.println(p);
    }
    }
    }

Stream stream implementation, optimization

public class Demo01Stream {
public static void main(String[] args) {
    //First Team
    ArrayList<String> one = new ArrayList<>();
    one.add("Dili Reba");
    one.add("Song Yuan Qiao");
    one.add("Su Bingtian");
    one.add("King of Kings");
    one.add("Lau Andy");
    one.add("Lao Zi");
    one.add("Zhuang Zi");
    one.add("Guo Fucheng");
    //1 The name of the member of the first team is only 3 words; Store in a new collection.
    //2, only the first three people are required after the first team is screened; Store in a new collection
    Stream<String> oneS = one.stream().filter(name->name.length()==3).limit(3);

    //Second Team
    ArrayList<String> two = new ArrayList<>();
    two.add("Gulinaza");
    two.add("Zhang Wuji");
    two.add("Zhao Liying");
    two.add("Zhang Sanfen");
    two.add("Nicholas");
    two.add("Zhang Tian Ai");
    two.add("Zhang sufficiently large");
    //The second team stores the names of only the members of the first team in a new collection
    //Do not store the first two in a new collection
    Stream<String> twoS = two.stream().filter(name->name.startsWith("Zhang")).skip(2);
    //Merge two teams, store
    //Create a Person object by name; Store in a new collection
    //Print Person Object
    Stream.concat(oneS,twoS).map(name->new Person(name)).forEach(s-> System.out.println(s));
    };
    }

Two Method References

When using Lambda expressions, the code we actually pass in is a solution: what parameters to do with.

Let's look at a simple functional interface to apply Lambda expressions:

@FunctionalInterface
public interface Printable {
void print(String str);
}

The only abstract method in the Printable interface, print, receives a string parameter for printing to display it. The code to use it through Lambda is simple:

public class Demo01PrintSimple {
private static void printString(Printable data) {
data.print("Hello, World!");
}
public static void main(String[] args) {
printString(s ‐> System.out.println(s));
}
}

The printString method calls the print method of the Printable interface, regardless of where the print method's implementation logic prints the string. The main method uses a Lambda expression to specify how the Printable function interface operates by outputting String data in the console after the type is deduced and therefore omitted.

Analysis: For the purpose of the Lambda expression, the string passed by the print parameter passes the parameter s to the System.out object, calling the method println in the out object to output the string

Be careful:

1, System. The out object is already 2, and the println method is already there

So we can use method references to optimize Lambda expressions using System.out directly refers to (calls) the println method

public class Demo02PrintRef {
private static void printString(Printable data) {
data.print("Hello, World!");
}
public static void main(String[] args) {
printString(System.out::println);
}

Method References

Double colon:: is a reference operator and the expression it is in is called a method reference. If the functional schema Lambda is expressing already exists in the implementation of a method, it can be referenced as a replacement for Lambda by double colons.

For example, in the example above, System. An overloaded println(String) method in the out object is exactly what we need. Then, for the printString method's function interface parameters, the comparison between the following two writings is completely equivalent:

Lambda expression: s -> System. Out. Println(s);

Method Reference Writing: System.out::println

The first semantics refers to taking the parameter and passing it to the System by Lambda. Out. Println method to process.

The semantics of the second equivalent writing refers to direct letting the system. The println method in out replaces Lambda. The execution of both methods is exactly the same, while the second method refers to a writing that duplicates the existing scheme

Note: The parameter passed in Lambda must be the type that the method in the method reference can receive, otherwise an exception will be thrown

2.1 Referencing member methods by object name

public class Demo04MethodRef {
//Member Method Exists
private static void printString(Printable lambda) {
lambda.print("Hello");
}
public static void main(String[] args) {
//create object
MethodRefObject obj = new MethodRefObject();
//Method Reference
printString(obj::printUpperCase);
}
}

2.2 Referencing static methods by class name

Reference static member methods by class name.

Class already exists, static method already exists, method reference can be used

Examples, de-absolute values

public class Demo06MethodRef {
private static void method(int num, Calcable lambda) {
System.out.println(lambda.calc(num));
}
public static void main(String[] args) {
method(‐10, Math::abs);
}
}

2.3 Referencing member methods through super

In this example, the following two writings are equivalent:

Lambda expression: () -> super. SayHello()

Method reference: super::sayHello

2.4 Referencing this class of methods through this

In this example, the following two writings are equivalent: Lambda expression: () -> this. BuyHouse() method reference: this::buyHouse

Constructor reference for class 2.5

Since the name of the constructor is exactly the same as the class name, it is not fixed. So the constructor reference uses the class name::new's format representation

Lambda expression: name -> new Person (name) method reference: Person::new

Constructor references to 2.6 arrays

Arrays are also subclasses of Object s, so they also have constructors, with slightly different syntax. A functional interface is required if it corresponds to a Lambda usage scenario.

Equivalent Writing:

Lambda expression: length -> new int[length]

Method reference: int[]::new

Keywords: Java

Added by bastienvans on Tue, 04 Jan 2022 09:21:15 +0200