当前位置:网站首页>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);
边栏推荐
- Infinite innovation in cloud "vision" | the 2022 Alibaba cloud live summit was officially launched
- Jetson AGX Orin CANFD 使用
- Computer win7 system desktop icon is too large, how to turn it down
- 防火墙基础之服务器区的防护策略
- Several ways of JS jump link
- asp. Netnba information management system VS development SQLSERVER database web structure c programming computer web page source code project detailed design
- Cvpr2022 | backdoor attack based on frequency injection in medical image analysis
- “百度杯”CTF比赛 2017 二月场,Web:include
- Instructions for mictr01 tester vibrating string acquisition module development kit
- 2022 cloud consulting technology series high availability special sharing meeting
猜你喜欢
Five pain points for big companies to open source
⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?
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
Ian Goodfellow, the inventor of Gan, officially joined deepmind as research scientist
Bill Gates posted his resume 48 years ago: "it's not as good-looking as yours."
电脑Win7系统桌面图标太大怎么调小
Jetson AGX Orin CANFD 使用
8大模块、40个思维模型,打破思维桎梏,满足你工作不同阶段、场景的思维需求,赶紧收藏慢慢学
Stm32cubemx, 68 sets of components, following 10 open source protocols
Spatiotemporal deformable convolution for compressed video quality enhancement (STDF)
随机推荐
Read PG in data warehouse in one article_ stat
上半年晋升 P8 成功,还买了别墅!
Xiaomi's path of chip self-development
[today in history] July 7: release of C; Chrome OS came out; "Legend of swordsman" issued
C 6.0 language specification approved
13 ux/ui/ue best creative inspiration websites in 2022
CTFshow,信息搜集:web4
寺岗电子称修改IP简易步骤
ES日志报错赏析-maximum shards open
How bad can a programmer be? Nima, they are all talents
CTFshow,信息搜集:web14
CPU与chiplet技术杂谈
#yyds干货盘点# 解决名企真题:交叉线
2022云顾问技术系列之高可用专场分享会
防火墙基础之服务器区的防护策略
JSON parsing instance (QT including source code)
Instructions d'utilisation de la trousse de développement du module d'acquisition d'accord du testeur mictr01
CTFshow,信息搜集:web13
Half an hour of hands-on practice of "live broadcast Lianmai construction", college students' resume of technical posts plus points get!
The method of parsing PHP to jump out of the loop and the difference between continue, break and exit