当前位置:网站首页>Stream learning notes
Stream learning notes
2022-07-07 14:55:00 【nsnsttn】
Stream introduction
Stream It's not a collection , It's not a data structure , Data cannot be saved
Stream It is similar to advanced Of Iterator , It can be used for algorithm and calculation
Unlike iterators , Stream Can parallelize operations , The data is divided into many segments , Processing in different threads
data source 、 Zero or more intermediate operations ( intermediate ) And zero or one terminal operation (terminal )
All intermediate operations are inert , Before the pipe starts working , Any operation will not produce any effect
The terminal operation is a bit like a faucet , Turn on the tap , Water will flow , The intermediate operation will be performed
One 、Strean How to create ?[Strean data source ]
The data source is an array
stream = Stream.of("1", "2", "3");
// Equate to
String[] arr = new String[]{
"1", "2", "3"};
Stream<String> stream = Arrays.stream(arr);
The data source is a collection
// aggregate List ,ap set Fine
List<String> list = new ArrayList<>();
list.add(" I ");
list.add(" yes ");
list.add(" aggregate ");
Stream<String> stream = list.stream(); // Sequential flow
ParallelStream<String> parallelStream =list.parallelStream(); // Parallel flow
adopt parallelStream()
You can create parallel streams , The default thread pool is not commonly used ThreadPoolTaskExecutor
It is ForkJoinPool
Two 、Stream How flow works ?[ Intermediate operation and terminal operation ]
A stream represents a collection of elements , We can do different kinds of operations on it , Used to perform calculations on these elements . It may sound a bit awkward , Let's talk in code :
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
.stream() // Create stream
.filter(s -> s.startsWith("c")) // filtering , Filter out c String for prefix
.map(String::toUpperCase) // Convert to uppercase
.sorted() // Sort
.forEach(System.out::println); // for Loop printing
// C1
// C2
We can do intermediate operation or terminal operation for convection .
What is intermediate operation ? What is terminal operation ?
Stream Intermediate operation , Terminal operation
- ①: The intermediate operation will return to a stream again , therefore , We can link multiple intermediate operations , Note that there is no need for semicolons . In the picture above
filter
Filter ,map
Object conversion ,sorted
Sort , It's an intermediate operation . - ②: Terminal operation is an end action of convection operation , Generally return to
void
Or a non flow result . In the picture aboveforEach
loop It's a termination operation .
After reading the above operation , Does it feel like a pipeline operation .
actually , Most stream operations support lambda Expressions as arguments , Correct understanding , It should be said to accept the implementation of a functional interface as a parameter .
3、 ... and 、 Different types of Stream flow
1. Distinguish according to the execution scheduling
1.1 Serial stream
1.2 Parallel flow
Stream The thread pool used by parallel streams in is ForkJoinPool
@Test
public void case6(){
List<Person> persons = Arrays.asList(
new Person("Max", 18),
new Person("Max", 18),
new Person("Peter", 23),
new Person("Pamela", 23),
new Person("David", 12),
new Person("David", 12),
new Person("David", 12));
// Create parallel streams directly parallelStream()
persons.parallelStream().peek((person)-> System.out.println(person.getName()+":"+Thread.currentThread().getName())).forEach(System.out::println);
// First use serial and then parallel parallel
persons.stream().distinct().parallel().peek((person)-> System.out.println(person.getName()+":"+Thread.currentThread().getName())).forEach(System.out::println);
}
2. Distinguish by data type
2.1 Basic data type stream (int,long,double)
- IntStream
- LongStream
- DoubleStream
2.2 Object flow (Object)
- Stream
Four 、 Intermediate operation
// First define an operation object, and then use
List<Person> persons = Arrays.asList(
new Person("Max", 18),
new Person("Max", 18),
new Person("Peter", 23),
new Person("Pamela", 23),
new Person("David", 12));
1.map
Traverse elements for editing , There is a return value , Can type conversion
@Test
public void testMap() {
Stream.of("apple", "banana", "orange", "watermelon", "grape")
.map(e -> {
e = e.substring(1, 1);
return e.length();
}) // Length converted to words int
.forEach(System.out::println); // Output
}
2.mapToInt
Object flow basic data flow , Of course these map Can do it ,mapToLong、mapToDouble And mapToInt similar
@Test
public void testMapToInt(){
Stream.of("apple", "banana", "orange", "waltermaleon", "grape")
.mapToInt(String::length) // Turn into int
.forEach(System.out::println);
}
3.peek
Traverse elements for editing , Print information , No return value , Cannot type cast ( In fact, it is provided for us to observe the elements of the flow )
@Test
public void tesPeek() {
Stream.of( new StringBuilder("apple") ,new StringBuilder("banana"),new StringBuilder("orange"),new StringBuilder("watermelon"),new StringBuilder("grape"))
.peek(s-> s.append("aa")) // Splicing aa
.map(StringBuilder::toString)
.forEach(System.out::println); // Output
}
4.flatMap
flatMap The function is to flatten the elements , Reconstitute the flattened elements Stream, And these Stream Serial merge into one Stream
//flatMap() Parameters , The return value of a functional interface is also a Stream flow
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
//map() Parameters of , The return value of the functional interface is Object
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
@Test
public void testFlatMap(){
Stream.of("a-b-c-d","e-f-i-g-h")
.flatMap(e->Stream.of(e.split("-")))
.forEach(System.out::println);
}
5.distinct
duplicate removal , Based on the equals Method to judge , If you want to customize your own bean duplicate removal , You need to rewrite equals Method , But this is not the only way , You can also customize filter rules
@Test
public void testDistinct() {
//Persons Object de duplication , The default according to equals
persons.stream()
.distinct()
.forEach(System.out::println);
//Integer duplicate removal
IntStream.of(1, 2, 2, 3)
.distinct()
.forEach(System.out::println);
}
6.Limit
Limit the number of elements
@Test
public void testLimit(){
//Persons Limit the number of elements
persons.stream()
.limit(3)
.forEach(System.out::println);
//Integer Limit the number of elements
Stream.of(1,2,3,4,5,6)
.limit(3) // Limit three
.forEach(System.out::println); // Will output The first three 1,2,3
}
7.skip
Skip the former n Elements
@Test
public void testSkip() {
//Persons Skip the former n Elements
persons.stream()
.skip(3)
.forEach(System.out::println);
//Integer Skip the former n Elements
Stream.of(1,2,3,4,5,6)
.skip(3) // Limit three
.forEach(System.out::println); // Will output The first three 1,2,3
}
8.sorted
Sort comparator The underlying dependence Comparable Realization , You can also provide a custom comparator
@Test
public void testSorted() {
///Persons Sort , Note the custom collation here
persons.stream()
.sorted(Comparator.comparingInt(Person::getAge).thenComparing(Person::getName))
.forEach(System.out::println);
//Integer Sort
Stream.of(1,2,4,3,5,6)
.sorted()
.forEach(System.out::println);
}
#IntStream( Proprietary approach )
- IntStream
- LongStream
- DoubleStream
1.mapToObj
Basic data flow object flow
@Test
public void testMapObject() {
// It turns into string object , And give String start +a
IntStream.of(1, 2, 3)
.mapToObj(String::valueOf)
.map(s -> "a" + s)
.forEach(System.out::println);
}
2.boxed
Automatic boxing , Put the basic type int Convert to object type Integer
@Test
public void testBoxed() {
// Convert basic type to object type
IntStream.range(0, 10).boxed().forEach(System.out::println);
// amount to
IntStream.range(0, 10).mapToObj(Integer::valueOf).forEach(System.out::println);
}
5、 ... and 、 Terminal operation
// Or the whole set first
List<Person> persons = Arrays.asList(
new Person("Max", 18),
new Person("Max", 18),
new Person("Peter", 23),
new Person("Pamela", 23),
new Person("David", 12));
1.forEach
forEach Not only is Stream Terminal operation of , And it is also the grammar sugar of the set
@Test
public void testForEach() {
persons.forEach(System.out::println);
}
2.count
Find the set length
@Test
public void testCount() {
long count = persons.stream().count();
System.out.println(count);
}
3.findFirst
Get the first element in the stream
@Test
public void testFindFirst() {
Optional<Person> optional = persons.stream().findFirst();
Person person = optional.orElse(null);
System.out.println(person);
}
4.findAny
Get any element in the stream
@Test
public void testFindAny() {
Optional<Person> optional = persons.stream().findAny();
Person person = optional.orElse(null);
System.out.println(person);
}
5.max
For maximum , Take the last one according to the rules
@Test
public void testMax() {
Optional<Person> max1 = persons.stream().max((p1, p2) -> {
return p1.getAge().compareTo(p2.getAge());
});
Person person1 = max1.orElse(null);
System.out.println(person1);
// simplify
Optional<Person> max2 = persons.stream().max(Comparator.comparing(Person::getAge));
Person person2 = max2.orElse(null);
System.out.println(person2);
}
6.min
For the minimum , According to the rules, take the first
@Test
public void testMin() {
Optional<Person> min1 = persons.stream().min((p1, p2) -> {
return p2.getAge().compareTo(p1.getAge());
});
Person person1 = min1.orElse(null);
System.out.println(person1);
// simplify
Optional<Person> min2 = persons.stream().min(Comparator.comparing(Person::getAge));
Person person2 = min1.orElse(null);
System.out.println(person2);
}
7.toArray
Turn array
@Test
public void testToArray() {
Object[] objects = persons.stream().toArray();
Arrays.stream(objects).forEach(System.out::println);
}
8.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 in the stream in turn to calculate on the basis of our calculation method , The calculation result is calculated in the following element
// Find the value of the maximum age
// have access to max( It's based on reduce) perhaps reduce
//reduce Sum up , Difference set , Ask for everything , In fact, it is the continuous calculation of a set of data
@Test
public void case5(){
List<Person> persons = Arrays.asList(
new Person("Max", 18),
new Person("Max", 18),
new Person("Peter", 23),
new Person("Pamela", 23),
new Person("David", 12),
new Person("David", 12),
new Person("David", 12));
// Minimum age
int minAge = persons.stream().mapToInt(Person::getAge).reduce(Integer.MAX_VALUE,new IntBinaryOperator(){
@Override
public int applyAsInt(int left, int right) {
return left > right?right:left;
}
});
System.out.println(minAge);
// Ask for the maximum age , Abbreviation
int maxAge = persons.stream().mapToInt(Person::getAge).reduce(Integer.MIN_VALUE, Math::max);
System.out.println(maxAge);
}
9.collect( above all )
Here is just a simple collection function , It's also the most commonly used , Referring to this article https://www.jianshu.com/p/6ee7e4cd5314
1.toList and toSet
@Test
public void testToListSet(){
List<Person> persons = Arrays.asList(
new Person("Max", 1),
new Person("Max", 2),
new Person("Peter", 3),
new Person("Pamela", 4),
new Person("David", 5));
//toList
List<Person> list1 = persons.stream().distinct().collect(Collectors.toList());
list1.forEach(System.out::println);
//toSet
Set<Person> set = persons.stream().collect(Collectors.toSet());
set.forEach(System.out::println);
}
2.toMap
@Test
public void testToMap(){
List<Person> persons = Arrays.asList(
new Person("Max", 1),
new Person("Max", 2),
new Person("Peter", 3),
new Person("Pamela", 4),
new Person("David", 5));
//key value It can be the object itself ( use Function.identity() Express ) It can also be an attribute
Map<Person, Person> collect1 = persons.stream().collect(Collectors.toMap(Function.identity(), Function.identity()));
collect1.forEach((k,v)->{
System.out.println(k+":"+v);
});
Map<Integer, String> collect2 = persons.stream().collect(Collectors.toMap(Person::getAge, Function.identity()));
collect2.forEach((k,v)->{
System.out.println(k+":"+v);
});
}
3.groupingBy
// There are three ways to overload
//groupingBy(Function)
//groupingBy(Function , Collector)
//groupingBy(Function, Supplier, Collector)
//Function Custom grouping rules
//Supplier Customize Map The type of , Default HashMap::new
//Collector Customize the format of each group , Default Collectors.toList()
@Test
public void testGroup(){
List<Person> persons = Arrays.asList(
new Person("Max", 1),
new Person("Min", 1),
new Person("Peter", 2),
new Person("Pamela", 3),
new Person("David", 4));
//1. Group by age
System.out.println(" Group by age ");
ConcurrentHashMap<Integer, Set<Person>> map1 = persons.stream().collect(Collectors.groupingBy(Person::getAge, ConcurrentHashMap::new, Collectors.toSet()));
map1.forEach((k,v)->{
System.out.println(k+":"+v);
});
//2. Custom grouping rules
System.out.println(" Custom grouping rules ");
Map<String, List<Person>> map2 = persons.stream().collect(Collectors.groupingBy((person -> {
if (person.getAge().equals(1)){
return " be equal to 1";
}
if (person.getAge().equals(2) || person.getAge().equals(3)){
return " be equal to 2 or 3";
}
if (person.getAge().equals(4)){
return " be equal to 4";
}
return null;
} )));
map2.forEach((k,v)->{
System.out.println(k+":"+v);
});
//3.partitioningBy Partition ( It can only be divided into two groups )
// Judge whether the age is 1
Map<Boolean, List<Person>> map3 = persons.stream().collect(Collectors.partitioningBy(person -> person.getAge().equals(1)));
map3.forEach((k,v)->{
System.out.println(k+":"+v);
});
}
4.Collectors.joining()
// String concatenation , There are three ways to overload
//Collectors.joining()
//Collectors.joining(CharSequence delimiter)
//Collectors.joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix)
//delimiter It's a separator , The default is ""
//prefix Is prefix , The default is ""
//suffix Is the suffix , The default is ""
@Test
public void testJoining(){
List<Person> persons = Arrays.asList(
new Person("Max", 1),
new Person("Peter", 2),
new Person("Pamela", 3),
new Person("David", 4));
String s1 = persons.stream().map(Person::getName).collect(Collectors.joining());
String s2 = persons.stream().map(Person::getName).collect(Collectors.joining("、"));
String s3 = persons.stream().map(Person::getName).collect(Collectors.joining("、","name:",";"));
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
#IntStream( Proprietary approach )
- IntStream
- LongStream
- DoubleStream
1.Reduce
Merge operation
//reduce There are two overload methods
//1. Parameters are starting values and operation rules , The return value is int Have a starting value , There are rules of operation , Two parameters , At this time, the returned type is the same as the starting value type .
T reduce(T identity, BinaryOperator<T> accumulator)
//2. Parameters are operation rules , The return value is Optional...
OptionalInt reduce(IntBinaryOperator op);
@Test
public void testReduce() {
// Have a starting value , There are rules of operation
int sum = IntStream.range(0, 10).reduce(0, (v1, v2) -> v1 - v2);
System.out.println(sum);
// The protocol operation returns optionalInt, It doesn't have to be worth it
OptionalInt reduce = IntStream.of().reduce((v1, v2) -> v1/v2);
reduce.ifPresent(System.out::println);
}
2.sum
Sum up
@Test
public void testSum() {
int sum = IntStream.rangeClosed(0, 10).sum();
System.out.println(sum);
}
3.average
averaging
@Test
public void testAverage() {
OptionalDouble optionalDouble = IntStream.of(-2, 2, -9, 10, 9).average();
double average = optionalDouble.getAsDouble();
System.out.println(average);
}
6、 ... and 、 matters needing attention
- Lazy evaluation ( If there is no termination operation , Only intermediate operations will not be performed )
- Flow is one-time ( Once a flow passes through a termination operation , This stream can no longer be used )
- The operation of convection will not affect the original data
No state : The processing of an element is not affected by the previous element ;
A stateful : The operation cannot continue until all elements have been obtained .
Non short circuit operation : All elements must be processed to get the final result ;
Short circuit operation : When you meet some elements that meet the conditions, you can get the final result , Such as A || B, as long as A by true, There is no need to judge B Result .
7、 ... and 、Optional
Optional It is to solve the bloated problem of null pointer verification
1. establish Optional
Optional.ofNullable(author)
Recommended
Optional.of(author)
If author==null A null pointer will be reported
public class OptionalDemo {
public static void main(String[] args) {
// Don't know author Is it empty , To prevent null pointer exceptions
Author author = OptionalDemo.getAuthor();
//1. We used to do this in vain
if (author != null) {
System.out.println(author.getAge());
}
//2.jdk8 You can then wrap this object as Optional<Author> object
Optional<Author> optionalAuthor = Optional.ofNullable(author);
System.out.println("optionalAuthor:" + optionalAuthor);
// Then judge
optionalAuthor.ifPresent(author1 -> System.out.println(author1.getName()));
//3. Package it in the method Optional
Optional<Author> optionalAuthor2 = OptionalDemo.getOptionalAuthor();
System.out.println("optionalAuthor2:" + optionalAuthor2);
optionalAuthor2.ifPresent(author1 -> System.out.println(author1.getName()));
}
public static Author getAuthor() {
Author author = new Author();
author.setAge(18);
author.setName(" zhaoyun ");
// return null;
return author;
}
public static Optional<Author> getOptionalAuthor() {
Author author = new Author();
author.setAge(20);
author.setName(" Zhang Fei ");
author = null;
//return Optional.of(author); // The incoming object cannot be empty
return Optional.ofNullable(author);
}
}
2. Safe consumption
ifPresent()
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
3. Get objects
3.1.get
( It is not recommended to use , The object is null Report errors NoSuchElementException)
Author author1 = optionalAuthor2.get();
3.2.orElseGet
( If the object is null, Custom return object )
optionalAuthor2.orElseGet(new Supplier<Author>() {
@Override
public Author get() {
Author author2 = new Author();
author2.setAge(18);
author2.setName(" Cao Cao ");
return author2;
}
});
3.3.orElseThrow
( If the object is null, Throw the self-defined exception )
optionalAuthor2.orElseThrow(new Supplier() {
@Override
public Exception get() {
return new Exception(" I rely on ");
}
});
// simplify
optionalAuthor2.orElseThrow((Supplier<Throwable>) () -> new RuntimeException(" I rely on "));
4. Filter
filter
Judge whether the object meets the standard , Non conforming ones will be regarded as objects null
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
5. Judge
ifPresent
Determines if the object is null , Empty return false, Not empty return true
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
6. Data conversion
map
Type conversion of data , and Stream The same as in China
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
// Return value It's also Optional object
Optional<String> optionalName = optionalAuthor2.map(Author::getName);
边栏推荐
猜你喜欢
What is the process of ⼀ objects from loading into JVM to being cleared by GC?
EfficientNet模型的完整细节
Pytorch model trains practical skills and breaks through the bottleneck of speed
Cocoscreator operates spine for animation fusion
防火墙基础之服务器区的防护策略
Navigation - are you sure you want to take a look at such an easy-to-use navigation framework?
暑期安全很重要!应急安全教育走进幼儿园
In the field of software engineering, we have been doing scientific research for ten years!
asp. Netnba information management system VS development SQLSERVER database web structure c programming computer web page source code project detailed design
Deformable convolutional dense network for enhancing compressed video quality
随机推荐
属性关键字ServerOnly,SqlColumnNumber,SqlComputeCode,SqlComputed
Read PG in data warehouse in one article_ stat
拜拜了,大厂!今天我就要去厂里
在软件工程领域,搞科研的这十年!
Es log error appreciation -maximum shards open
Cocoscreator operates spine for animation fusion
Read PG in data warehouse in one article_ stat
寺岗电子称修改IP简易步骤
Pinduoduo lost the lawsuit, and the case of bargain price difference of 0.9% was sentenced; Wechat internal test, the same mobile phone number can register two account functions; 2022 fields Awards an
Base64 encoding
Yyds dry goods inventory # solve the real problem of famous enterprises: cross line
13 ux/ui/ue best creative inspiration websites in 2022
[Yugong series] go teaching course 005 variables in July 2022
Pandora IOT development board learning (HAL Library) - Experiment 12 RTC real-time clock experiment (learning notes)
Delete a whole page in word
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Notes HCIA
安恒堡垒机如何启用Radius双因素/双因子(2FA)身份认证
Spatiotemporal deformable convolution for compressed video quality enhancement (STDF)
暑期安全很重要!应急安全教育走进幼儿园