当前位置:网站首页>Stream stream
Stream stream
2022-07-24 11:19:00 【Zhang Shao】
List of articles
- Functional programming -Stream flow
- 1. summary
- 2. Lambda expression
- 3. Stream flow
- 4. Optional
- 5. Functional interface
- 6. Method reference
- 7. Advanced usage
Functional programming -Stream flow
1. summary
1.1 What is learning ?
- Be able to understand the code in the company
- High efficiency in dealing with collections in large quantities
- Code readability
- Destroy nested hell
// Check the rating of minor writers in 70 The above books Writers and books may repeat due to ocean currents , De duplication is required
List<Book> bookList = new ArrayList<>();
Set<Book> uniqueBookValues = new HashSet<>();
Set<Author> uniqueAuthorValues = new HashSet<>();
for (Author author : authors) {
if (uniqueAuthorValues.add(author)) {
if (author.getAge() < 18) {
List<Book> books = author.getBooks();
for (Book book : books) {
if (book.getScore() > 70) {
if (uniqueBookValues.add(book)) {
bookList.add(book);
}
}
}
}
}
}
System.out.println(bookList);
List<Book> collect = authors.stream()
.distinct()
.filter(author -> author.getAge() < 18)
.map(author -> author.getBooks())
.flatMap(Collection::stream)
.filter(book -> book.getScore() > 70)
.distinct()
.collect(Collectors.toList());
System.out.println(collect);
1.2 Functional programming ideas
1.2.1 Concept
Object oriented thinking needs to focus on what objects are used to accomplish what things . The idea of functional programming is similar to the function in our mathematics . It mainly focuses on what is done with the data .
1.2.2 advantage
- The code is concise , Fast development
- Close to natural language , Easy to understand
- Easy to " Concurrent programming "
2. Lambda expression
2.1 summary
Lambda yes JDK8 A grammar sugar in . He can simplify the writing of some anonymous inner classes . It is an important embodiment of the idea of functional programming . Let's not focus on what the object is . It's more about what we do with the data .
2.2 Core principles
It can be deduced and omitted
2. 3 The basic format
( parameter list )->{
Code }
Patients with a
When we create a thread and start it, we can use the writing method of anonymous inner class :
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(" You know what? I'm better than you think I want to be by your side ");
}
}).start();
have access to Lambda Modify it in the format of . Revised as follows :
new Thread(()->{
System.out.println(" You know what? I'm better than you think I want to be by your side ");
}).start();
Example 2 :
The existing methods are defined as follows , among IntBinaryOperator It's an interface . First call the method using the writing method of anonymous inner class .
public static int calculateNum(IntBinaryOperator operator){
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
public static void main(String[] args) {
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(i);
}
Lambda How to write it :
public static void main(String[] args) {
int i = calculateNum((int left, int right)->{
return left + right;
});
System.out.println(i);
}
Example 3 :
The existing methods are defined as follows , among IntPredicate It's an interface . First call the method using the writing method of anonymous inner class .
public static void printNum(IntPredicate predicate){
int[] arr = {
1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
if(predicate.test(i)){
System.out.println(i);
}
}
}
public static void main(String[] args) {
printNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value%2==0;
}
});
}
Lambda How to write it :
public static void main(String[] args) {
printNum((int value)-> {
return value%2==0;
});
}
public static void printNum(IntPredicate predicate){
int[] arr = {
1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
if(predicate.test(i)){
System.out.println(i);
}
}
}
Example 4 :
The existing methods are defined as follows , among Function It's an interface . First call the method using the writing method of anonymous inner class .
public static <R> R typeConver(Function<String,R> function){
String str = "1235";
R result = function.apply(str);
return result;
}
public static void main(String[] args) {
Integer result = typeConver(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
});
System.out.println(result);
}
Lambda How to write it :
Integer result = typeConver((String s)->{
return Integer.valueOf(s);
});
System.out.println(result);
Example 5 :
The existing methods are defined as follows , among IntConsumer It's an interface . First call the method using the writing method of anonymous inner class .
public static void foreachArr(IntConsumer consumer){
int[] arr = {
1,2,3,4,5,6,7,8,9,10};
for (int i : arr) {
consumer.accept(i);
}
}
public static void main(String[] args) {
foreachArr(new IntConsumer() {
@Override
public void accept(int value) {
System.out.println(value);
}
});
}
Lambda How to write it :
public static void main(String[] args) {
foreachArr((int value)->{
System.out.println(value);
});
}
2.4 Omit the rule
- Parameter types can be omitted
- Curly braces when the method body has only one sentence of code return And the semicolon of the only sentence code can be omitted
- When the method has only one parameter, the parentheses can be omitted
- If you can't remember the above rules, you can also omit them
3. Stream flow
3.1 summary
Java8 Of Stream Using the functional programming mode , Like its name , It can be used to perform chain flow operations on sets or arrays . We can operate on arrays or collections more conveniently .
3.2 Case data preparation
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode// Used for later de duplication
public class Author {
//id
private Long id;
// full name
private String name;
// Age
private Integer age;
// brief introduction
private String intro;
// works
private List<Book> books;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode// Used for later de duplication
public class Book {
//id
private Long id;
// Title
private String name;
// classification
private String category;
// score
private Integer score;
// brief introduction
private String intro;
}
private static List<Author> getAuthors() {
// Data initialization
Author author = new Author(1L," Mondo ",33," A Zuan man who understands philosophy from a kitchen knife ",null);
Author author2 = new Author(2L," Arazo ",15," The wind can't catch up with his thinking speed ",null);
Author author3 = new Author(3L," easy ",14," It's the world that limits his thinking ",null);
Author author4 = new Author(3L," easy ",14," It's the world that limits his thinking ",null);
// List of books
List<Book> books1 = new ArrayList<>();
List<Book> books2 = new ArrayList<>();
List<Book> books3 = new ArrayList<>();
books1.add(new Book(1L," On both sides of the knife are light and darkness "," philosophy , love ",88," Divide love and hate with a knife "));
books1.add(new Book(2L," One cannot die by the same knife "," Personal growth , love ",99," Tell how to understand the truth from failure "));
books2.add(new Book(3L," Where the wind cannot reach "," philosophy ",85," Take you to the end of the world with your mind "));
books2.add(new Book(3L," Where the wind cannot reach "," philosophy ",85," Take you to the end of the world with your mind "));
books2.add(new Book(4L," Blow or not blow "," love , Biography ",56," A philosopher's view of love is doomed to be difficult to understand his era "));
books3.add(new Book(5L," Your sword is my sword "," love ",56," I can't imagine a warrior being so tolerant to his partner "));
books3.add(new Book(6L," Wind and sword "," Biography ",100," What kind of sparks will be aroused by the collision between the soul and body of two philosophers ?"));
books3.add(new Book(6L," Wind and sword "," Biography ",100," What kind of sparks will be aroused by the collision between the soul and body of two philosophers ?"));
author.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
List<Author> authorList = new ArrayList<>(Arrays.asList(author,author2,author3,author4));
return authorList;
}
3.3 Quick start
3.3.1 demand
We can call getAuthors Method to get the collection of Writers . Now you need to print all the documents that are younger than 18 The name of the writer , And pay attention to weight removal .
3.3.2 Realization
// Print all children younger than 18 The name of the writer , And pay attention to weight removal
List<Author> authors = getAuthors();
authors.
stream()// Convert a collection into a stream
.distinct()// First remove the duplicate writers
.filter(author -> author.getAge()<18)// The screening age is less than 18 Of
.forEach(author -> System.out.println(author.getName()));// Traverse print name
3.4 Common operations
3.4.1 Create stream
Single column set : A collection of objects .stream()
List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();
Array :Arrays.stream( Array ) Or use Stream.of To create
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);
Double column set : Convert to a single column set and then create
Map<String,Integer> map = new HashMap<>();
map.put(" Crayon Shin Chan ",19);
map.put(" The spots ",17);
map.put(" The sun shines on the sun ",16);
Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
3.4.2 Intermediate operation
filter【 Filter 】
You can conditionally filter the elements in the stream , Only those that meet the filtering conditions can remain in the flow .
for example :
Print all names longer than 1 The name of the author
List<Author> authors = getAuthors();
authors.stream()
.filter(author -> author.getName().length()>1)
.forEach(author -> System.out.println(author.getName()));
️map【 Calculation / transformation 】
The elements in the convection can be calculated or converted .
for example :
Print the names of all writers
List<Author> authors = getAuthors();
authors
.stream()
.map(author -> author.getName())
.forEach(name->System.out.println(name));
// Print the names of all writers
List<Author> authors = getAuthors();
// authors.stream()
// .map(author -> author.getName())
// .forEach(s -> System.out.println(s));
authors.stream()
.map(author -> author.getAge())
.map(age->age+10)
.forEach(age-> System.out.println(age));
distinct【 duplicate removal 】
You can remove duplicate elements from the stream .
for example :
Print the names of all writers , And there must be no duplicate elements .
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.forEach(author -> System.out.println(author.getName()));
Be careful :distinct The method is to rely on Object Of equals Method to determine whether it is the same object . So we need to pay attention to rewriting equals Method .
sorted【 Sort 】
You can sort the elements in the stream .
for example :
The elements in the convection are sorted in descending order by age , And there must be no duplicate elements .
List<Author> authors = getAuthors();
// The elements in the convection are sorted in descending order by age , And there must be no duplicate elements .
authors.stream()
.distinct()
.sorted()
.forEach(author -> System.out.println(author.getAge()));
List<Author> authors = getAuthors();
// The elements in the convection are sorted in descending order by age , And there must be no duplicate elements .
authors.stream()
.distinct()
.sorted((o1, o2) -> o2.getAge()-o1.getAge())
.forEach(author -> System.out.println(author.getAge()));
Be careful : If you call an empty parameter sorted() Method , The elements in the need stream are implemented Comparable.
limit【 Limit 】
You can set the maximum length of the stream , The excess will be discarded .
for example :
The elements in the convection are sorted in descending order by age , And there must be no duplicate elements , Then print the names of the two oldest Writers .
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.sorted()
.limit(2)
.forEach(author -> System.out.println(author.getName()));
skip【 Skip the element 】
Skip previous in stream n Elements , Return the remaining elements
for example :
Print writers other than the oldest , No duplicate elements are required , And in descending order of age .
// Print writers other than the oldest , No duplicate elements are required , And in descending order of age .
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.sorted()
.skip(1)
.forEach(author -> System.out.println(author.getName()));
flatMap【 transformation 】
map Only one object can be converted into another object as an element in the stream . and flatMap You can convert an object into multiple objects as elements in the stream .
Patients with a :
Print the names of all books . Require duplicate elements to be de duplicated .
// Print the names of all books . Require duplicate elements to be de duplicated .
List<Author> authors = getAuthors();
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.forEach(book -> System.out.println(book.getName()));
Example 2 :
Print all categories of existing data . De duplication of classification is required . This format cannot appear : philosophy , love
// Print all categories of existing data . De duplication of classification is required . This format cannot appear : philosophy , love love
List<Author> authors = getAuthors();
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.flatMap(book -> Arrays.stream(book.getCategory().split(",")))
.distinct()
.forEach(category-> System.out.println(category));
3.4.3 End operation
forEach【 Traverse 】
Traverse the elements in the stream , We use the passed in parameters to specify what specific operations to perform on the traversed elements .
Example :
Output the names of all writers
// Output the names of all writers
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getName())
.distinct()
.forEach(name-> System.out.println(name));
count【 Number of Statistics 】
It can be used to obtain the number of elements in the current stream .
Example :
The number of books printed by these writers , Pay attention to removing duplicate elements .
// The number of books printed by these writers , Pay attention to removing duplicate elements .
List<Author> authors = getAuthors();
long count = authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.count();
System.out.println(count);
max&min【 The most value 】
Can be used to or the maximum value in the stream .
Example :
Get the highest and lowest scores of the books produced by these writers respectively and print .
// Get the highest and lowest scores of the books produced by these writers respectively and print .
//Stream<Author> -> Stream<Book> ->Stream<Integer> -> evaluation
List<Author> authors = getAuthors();
Optional<Integer> max = authors.stream()
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.max((score1, score2) -> score1 - score2);
Optional<Integer> min = authors.stream()
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.min((score1, score2) -> score1 - score2);
System.out.println(max.get());
System.out.println(min.get());
collect【 Convert to set 】
Convert the current stream into a collection .
Example :
Get a file that holds the names of all authors List aggregate .
// Get a file that holds the names of all authors List aggregate .
List<Author> authors = getAuthors();
List<String> nameList = authors.stream()
.map(author -> author.getName())
.collect(Collectors.toList());
System.out.println(nameList);
Get a list of all book titles Set aggregate .
// Get a list of all book titles Set aggregate .
List<Author> authors = getAuthors();
Set<Book> books = authors.stream()
.flatMap(author -> author.getBooks().stream())
.collect(Collectors.toSet());
System.out.println(books);
Get one Map aggregate ,map Of key Name the author ,value by List
// Get one Map aggregate ,map Of key Name the author ,value by List<Book>
List<Author> authors = getAuthors();
Map<String, List<Book>> map = authors.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
System.out.println(map);
Find and match
anyMatch【 Any match 】
It can be used to judge whether there are any matching elements , The result is boolean type .
Example :
Judge whether there is an age in 29 The above Writers
// Judge whether there is an age in 29 The above Writers
List<Author> authors = getAuthors();
boolean flag = authors.stream()
.anyMatch(author -> author.getAge() > 29);
System.out.println(flag);
allMatch【 All matches 】
It can be used to judge whether they all meet the matching conditions , The result is boolean type . If they all agree, the result is true, Otherwise, the result is false.
Example :
Judge whether all writers are adults
// Judge whether all writers are adults
List<Author> authors = getAuthors();
boolean flag = authors.stream()
.allMatch(author -> author.getAge() >= 18);
System.out.println(flag);
noneMatch【 No match 】
You can judge whether the elements in the flow do not meet the matching conditions . If they don't match, the result is true, Otherwise, the result is false
Example :
Judge whether writers have not exceeded 100 Year old .
// Judge whether writers have not exceeded 100 Year old .
List<Author> authors = getAuthors();
boolean b = authors.stream()
.noneMatch(author -> author.getAge() > 100);
System.out.println(b);
findAny【 Find any 】
Get any element in the stream . This method has no way to ensure that the first element in the stream is obtained .
Example :
Get any one older than 18 The writer of , If it exists, output his name
// Get any one older than 18 The writer of , If it exists, output his name
List<Author> authors = getAuthors();
Optional<Author> optionalAuthor = authors.stream()
.filter(author -> author.getAge()>18)
.findAny();
optionalAuthor.ifPresent(author -> System.out.println(author.getName()));
findFirst【 find first 】
Get the first element in the stream .
Example :
Get the youngest writer , And output his name .
// Get the youngest writer , And output his name .
List<Author> authors = getAuthors();
Optional<Author> first = authors.stream()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.findFirst();
first.ifPresent(author -> System.out.println(author.getName()));
️reduce【 Merger 】
The data in the convection will calculate a result according to the calculation method you specify .( Reduction operation )
reduce Its function is to turn stream Combine the elements in , We can pass in an initial value , It will take the elements and initialization values in the stream in turn according to our calculation method , The calculation result is then calculated with the following elements .
reduce The internal calculation method of the overloaded form of the two parameters is as follows :
T result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
among identity Is the initial value that we can pass in through the method parameters ,accumulator Of apply The specific calculation is also determined by the method parameters .
Example :
Use reduce Find the sum of the ages of all authors
// Use reduce Find the sum of the ages of all authors
List<Author> authors = getAuthors();
Integer sum = authors.stream()
.distinct()
.map(author -> author.getAge())
.reduce(0, (result, element) -> result + element);
System.out.println(sum);
Use reduce Find the maximum age of all authors
// Use reduce Find the maximum age of all authors
List<Author> authors = getAuthors();
Integer max = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
System.out.println(max);
Use reduce Find the minimum age of all authors
// Use reduce Find the minimum age of all authors
List<Author> authors = getAuthors();
Integer min = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MAX_VALUE, (result, element) -> result > element ? element : result);
System.out.println(min);
reduce Overloaded form of a parameter, internal calculation , Take the first element as the initialization value
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
}
else
result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();
If the overload method of a parameter is used to find the minimum value, the code is as follows :
// Use reduce Find the minimum age of all authors
List<Author> authors = getAuthors();
Optional<Integer> minOptional = authors.stream()
.map(author -> author.getAge())
.reduce((result, element) -> result > element ? element : result);
minOptional.ifPresent(age-> System.out.println(age));
3.5 matters needing attention
- Lazy evaluation ( If there is no termination operation , No intermediate operation will be performed )
- Flow is one-time ( Once a stream object passes through a termination operation . This stream can no longer be used )
- It won't affect the original data ( We can do a lot of data processing in the stream . But under normal circumstances, it will not affect the elements in the original set . This is often what we expect )
4. Optional
4.1 summary
When we write code, the most common is null pointer exception . So in many cases, we need to make all kinds of non empty judgments .
for example :
Author author = getAuthor();
if(author!=null){
System.out.println(author.getName());
}
Especially when the attribute in the object is still an object . This judgment will be more .
Too many judgment statements will make our code look bloated .
So in JDK8 Introduced in Optional, Develop the use of Optional You can write more elegant code to avoid null pointer exceptions .
And in many functional programming related API Also used in Optional, If you don't use Optional It will also affect the learning of functional programming .
4.2 Use
4.2.1 ️ Create objects
Optional It's like packaging , We can encapsulate our specific data Optional Inside object . Then we use Optional The encapsulated method can operate the encapsulated data in a very elegant way to avoid null pointer exceptions .
We usually use Optional Of Static methods ofNullable Encapsulate data into a Optional object . Whether the parameter passed in is null No problem .
Author author = getAuthor();
Optional<Author> authorOptional = Optional.ofNullable(author);
You may find it troublesome to add a line of code to encapsulate the data . But if you transform getAuthor Method , Let its return value be encapsulated Optional Words , It will be much more convenient for us to use .
And in the actual development, many of our data are obtained from the database .Mybatis from 3.5 The version can and already supports Optional 了 . We can put dao The return value type of the method is defined as Optional type ,MyBastis Will encapsulate the data into Optional Object returns . The encapsulation process does not need our own operation .
If you Make sure an object is not empty Can be used Optional Of Static methods of To encapsulate the data into Optional object .
Author author = new Author();
Optional<Author> authorOptional = Optional.of(author);
But be sure to pay attention to , If you use of The parameter passed in must not be null.( Try passing in null What will happen )
If the return value type of a method is Optional type . If we find that the return value of a calculation is null, At this time, we need to put null Encapsulated into Optional Object returns . You can use Optional Of Static methods empty To encapsulate .
Optional.empty()
author == null ? Optional.empty(): Optional.of(author);
So in the end, which way do you think will be more convenient ?ofNullable
4.2.2 ️ Safe consumption value
We got one Optional After the object, you must use the data in it . At this time, we can use its ifPresent Method pair to consume the value .
This method will determine whether the encapsulated data is empty , When it is not empty, the specific consumption code will be executed . This makes it safer to use .
for example , The following writing method gracefully avoids null pointer exceptions .
Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
authorOptional.ifPresent(author -> System.out.println(author.getName()));
4.2.3 Get value
If we want to get the value and process it ourselves, we can use get Method to get , But not recommended . Because when Optional An exception occurs when the internal data is empty .
4.2.4 Secure get value
If we expect to get value safely . We don't recommend using get Method , But use Optional The following methods are provided .
orElseGet
Get the data and set the default value when the data is empty . If the data is not empty, you can get the data . If it is empty, the object will be created according to the parameters you pass in and returned as the default value .
Optional<Author> authorOptional = Optional.ofNullable(getAuthor()); Author author1 = authorOptional.orElseGet(() -> new Author());orElseThrow
get data , If the data is not empty, you can get the data . If it is empty, create an exception throw according to the parameters you pass in .
Optional<Author> authorOptional = Optional.ofNullable(getAuthor()); try { Author author = authorOptional.orElseThrow((Supplier<Throwable>) () -> new RuntimeException("author It's empty ")); System.out.println(author.getName()); } catch (Throwable throwable) { throwable.printStackTrace(); }
4.2.5 Filter
We can use filter Method to filter the data . If there were data , But it doesn't match the judgment , It will also become a data free Optional object .
Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
authorOptional.filter(author -> author.getAge()>100).ifPresent(author -> System.out.println(author.getName()));
4.2.6 Judge
We can use isPresent Method to judge whether there is data . If it is null, the return value is false, If it's not empty , The return value is true. But this approach does not reflect Optional The benefits of , More recommended ifPresent Method .
Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
if (authorOptional.isPresent()) {
System.out.println(authorOptional.get().getName());
}
Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
authorOptional.orElse("")
4.2.7 Data conversion
Optional It also provides map It allows our to convert the data , And the converted data is still Optional Packed , Ensure the safety of our use .
For example, we want to get a collection of writers' books .
private static void testMap() {
Optional<Author> authorOptional = getAuthorOptional();
Optional<List<Book>> optionalBooks = authorOptional.map(author -> author.getBooks());
optionalBooks.ifPresent(books -> System.out.println(books));
}
5. Functional interface
5.1 summary
There is only one abstract method The interface is called our function .
JDK The functional interfaces of are added **@FunctionalInterface** Note to identify . But no matter whether the annotation is added or not, as long as there is only one abstract method in the interface , It's all functional interfaces .
5.2 Common functional interfaces
Consumer Consumer interface
According to the parameter list and return value type of the abstract method, we know , We can consume the passed in parameters in the method .

Function Calculation adapter
According to the parameter list and return value type of the abstract method, we know , We can calculate or convert the passed parameters in the method , Return the result to

Predicate Judgment interface
According to the parameter list and return value type of the abstract method, we know , We can judge the incoming parameter conditions in the method , Return the judgment result

Supplier Production interface
According to the parameter list and return value type of the abstract method, we know , We can create objects in methods , Return the created object to

5.3 Common default methods
and
We are using Predicate It may be necessary to splice judgment conditions when interfacing . and and The method is equivalent to using && To splice two judgment conditions
for example :
Print writers are older than 17 And the length of the name is greater than 1 The writer of .
List<Author> authors = getAuthors(); Stream<Author> authorStream = authors.stream(); authorStream.filter(new Predicate<Author>() { @Override public boolean test(Author author) { return author.getAge()>17; } }.and(new Predicate<Author>() { @Override public boolean test(Author author) { return author.getName().length()>1; } })).forEach(author -> System.out.println(author));or
We are using Predicate It may be necessary to splice judgment conditions when interfacing . and or The method is equivalent to using || To splice two judgment conditions .
for example :
Print writers are older than 17 Or the length of the name is less than 2 The writer of .
// Print writers are older than 17 Or the length of the name is less than 2 The writer of . List<Author> authors = getAuthors(); authors.stream() .filter(new Predicate<Author>() { @Override public boolean test(Author author) { return author.getAge()>17; } }.or(new Predicate<Author>() { @Override public boolean test(Author author) { return author.getName().length()<2; } })).forEach(author -> System.out.println(author.getName()));negate
Predicate Methods in interfaces .negate The method is equivalent to adding a before the judgment ! Representation inversion
for example :
Print writers are no older than 17 The writer of .
// Print writers are no older than 17 The writer of . List<Author> authors = getAuthors(); authors.stream() .filter(new Predicate<Author>() { @Override public boolean test(Author author) { return author.getAge()>17; } }.negate()).forEach(author -> System.out.println(author.getAge()));
6. Method reference
We are using lambda when , If there is only one method call in the method body ( Including construction method ), We can use method references to further simplify the code .
6.1 Recommended use
We are using lambda There is no need to consider when to use method reference , In which way to reference , What is the format of the method reference . We just need to finish writing lambda Method found that the method body has only one line of code , And when calling a method, use the shortcut key to try whether it can be converted into a method reference .
When we use more method references, we can also write method references directly slowly .
6.2 The basic format
Class name or object name :: Method name
6.3 Grammar explanation ( understand )
6.3.1 Static methods that reference classes
In fact, it refers to the static method of a class
Format
Class name :: Method name
Use the premise
If we're rewriting methods , In method body There's only one line of code , And this line of code is Called a static method of a class , And we're going to rewrite All parameters in the abstract method are passed into the static method in order , At this time, we can reference the static methods of the class .
for example :
The following code can be simplified by method reference
List<Author> authors = getAuthors();
Stream<Author> authorStream = authors.stream();
authorStream.map(author -> author.getAge())
.map(age->String.valueOf(age));
Be careful , If the method we rewrite has no parameters , The called method also has no parameters, which is equivalent to meeting the above rules .
The optimization is as follows :
List<Author> authors = getAuthors();
Stream<Author> authorStream = authors.stream();
authorStream.map(author -> author.getAge())
.map(String::valueOf);
6.3.2 Instance methods that reference objects
Format
Object name :: Method name
Use the premise
If we're rewriting methods , In method body There's only one line of code , And this line of code is Called the member method of an object , And we're going to rewrite All parameters in the abstract method are passed into the member method in order , At this time, we can reference the instance method of the object
for example :
List<Author> authors = getAuthors();
Stream<Author> authorStream = authors.stream();
StringBuilder sb = new StringBuilder();
authorStream.map(author -> author.getName())
.forEach(name->sb.append(name));
After optimization :
List<Author> authors = getAuthors();
Stream<Author> authorStream = authors.stream();
StringBuilder sb = new StringBuilder();
authorStream.map(author -> author.getName())
.forEach(sb::append);
6.3.4 Reference class instance methods
Format
Class name :: Method name
Use the premise
If we're rewriting methods , In method body There's only one line of code , And this line of code is The member method that called the first parameter , And we're going to All the remaining parameters in the overridden abstract method are passed into the member method in order , At this time, we can reference the instance method of the class .
for example :
interface UseString{
String use(String str,int start,int length);
}
public static String subAuthorName(String str, UseString useString){
int start = 0;
int length = 1;
return useString.use(str,start,length);
}
public static void main(String[] args) {
subAuthorName(" Sangeng thatched cottage ", new UseString() {
@Override
public String use(String str, int start, int length) {
return str.substring(start,length);
}
});
}
The optimization is as follows :
public static void main(String[] args) {
subAuthorName(" Sangeng thatched cottage ", String::substring);
}
6.3.5 Constructor reference
If a line of code in the method body is a constructor, you can use the constructor reference .
Format
Class name ::new
Use the premise
If we're rewriting methods , In method body There's only one line of code , And this line of code is Calling the constructor of a class , And we put All parameters in the abstract method to be rewritten are passed into the constructor in order , At this point, we can reference the constructor .
for example :
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getName())
.map(name->new StringBuilder(name))
.map(sb->sb.append("- Sanguine ").toString())
.forEach(str-> System.out.println(str));
After optimization :
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getName())
.map(StringBuilder::new)
.map(sb->sb.append("- Sanguine ").toString())
.forEach(str-> System.out.println(str));
7. Advanced usage
Basic data type optimization
We used a lot before Stream Because all methods use generics . Therefore, the parameters and return values involved are reference data types .
Even if we operate on integers and decimals , But they actually use their packaging .JDK5 The automatic packing and unpacking introduced in allows us to use the corresponding packing class as easily as using the basic data type . But you must know that packing and unpacking must take time . Although it takes a lot of time . But when a large amount of data is repeatedly packed and unpacked , You can't ignore this loss of time .
So in order to optimize the time consumption of this part .Stream There are also many methods specifically for basic data types .
for example :mapToInt,mapToLong,mapToDouble,flatMapToInt,flatMapToDouble etc. .
private static void test27() {
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getAge())
.map(age -> age + 10)
.filter(age->age>18)
.map(age->age+2)
.forEach(System.out::println);
authors.stream()
.mapToInt(author -> author.getAge())
.map(age -> age + 10)
.filter(age->age>18)
.map(age->age+2)
.forEach(System.out::println);
}
Parallel flow
When there are a large number of elements in the stream , We can use parallel flow to improve the efficiency of operation . In fact, parallel flow is to assign tasks to multiple threads to complete . If we implement it in code, it will be very complex , And it requires you to have enough understanding and understanding of concurrent programming . And if we use Stream Words , We only need to modify the call of a method to use parallel flow to help us realize , To improve efficiency .
parallel Method can convert a serial stream into a parallel stream .
private static void test28() {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = stream.parallel()
.peek(new Consumer<Integer>() {
@Override
public void accept(Integer num) {
System.out.println(num+Thread.currentThread().getName());
}
})
.filter(num -> num > 5)
.reduce((result, ele) -> result + ele)
.get();
System.out.println(sum);
}
It can also be done through parallelStream Get parallel stream objects directly .
List<Author> authors = getAuthors();
authors.parallelStream()
.map(author -> author.getAge())
.map(age -> age + 10)
.filter(age->age>18)
.map(age->age+2)
.forEach(System.out::println);
边栏推荐
- cgo+gSoap+onvif学习总结:9、go和c进行socket通信进行onvif协议处理
- Introduction to kubernetes Basics
- Text message verification of web crawler
- Redis 100 million level data storage scheme hash slot partition
- tcp 服务端接收数据处理思路梳理,以及select: Invalid argument报错 笔记
- RetinaNet:Focal Loss for Dense Object Detection
- 【Golang】golang实现sha256加密函数
- [white hat talks about web security] Chapter 2 browser security
- 自动推理的逻辑06--谓词演算
- Lanqiao cup provincial training camp - stack and recursion
猜你喜欢

Jmeter-Runtime控制器

LDR6028充电OTG直播线直播声卡音频转接器最具性价比方案

性能测试总结(一)---基础理论篇

RRPN:Arbitrary-Oriented Scene Text Detection via Rotation Proposals

Zynq TTC usage

ctfshow ThinkPHP专题 1

This is the right way for developers to open artifact!

这个应该是全网最全的接口测试工具之postman

Taking advantage of the momentum, oceanbase promotes the lean growth of digital payment

JMeter interface test steps - Installation Tutorial - script recording - concurrent test
随机推荐
【Golang】golang中map元素的删除和清空
[white hat talks about web security] Chapter 1 my security world view
Capture and handling of JDBC exception sqlexception
Performance test summary (I) -- basic theory
[live registration] analysis of location cache module and detailed explanation of OCP monitoring and alarm
[golang] golang realizes sending wechat service number template messages
PIP update command
07 [use of path and files classes]
CSDN blog removes the uploaded image watermark
pip更新命令
FastCGI运行原理及php-fpm参数配置
【反序列化漏洞-01】序列化与反序列化简介
Idea background image set
UNIX C language POSIX thread creation, obtaining thread ID, merging thread, separating thread, terminating thread, thread comparison
【Golang】golang实现发送微信服务号模板消息
2022, the average salary of the soft tester, after reading it, I was instantly cool
MySQL根据备注查询表、字段
MySQL查询字段匹配某个规则的记录
Working principle and function application of frequency converter
2018 arXiv | Objective-Reinforced Generative Adversarial Networks (ORGAN) for Sequence Generation Mo