当前位置:网站首页>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);
边栏推荐
- 广州开发区让地理标志产品助力乡村振兴
- EfficientNet模型的完整细节
- 安恒堡垒机如何启用Radius双因素/双因子(2FA)身份认证
- 时空可变形卷积用于压缩视频质量增强(STDF)
- 激光雷达lidar知识点滴
- CTFshow,信息搜集:web13
- Navigation — 这么好用的导航框架你确定不来看看?
- Yyds dry goods inventory # solve the real problem of famous enterprises: cross line
- Lidar knowledge drops
- Navigation - are you sure you want to take a look at such an easy-to-use navigation framework?
猜你喜欢
Novel Slot Detection: A Benchmark for Discovering Unknown Slot Types in the Dialogue System
因员工将密码设为“123456”,AMD 被盗 450Gb 数据?
“百度杯”CTF比赛 2017 二月场,Web:include
leetcode:648. Word replacement [dictionary tree board + find the shortest matching prefix among several prefixes]
Infinite innovation in cloud "vision" | the 2022 Alibaba cloud live summit was officially launched
CTFshow,信息搜集:web5
广州开发区让地理标志产品助力乡村振兴
Niuke real problem programming - Day11
Apache multiple component vulnerability disclosure (cve-2022-32533/cve-2022-33980/cve-2021-37839)
Today's sleep quality record 78 points
随机推荐
因员工将密码设为“123456”,AMD 被盗 450Gb 数据?
Instructions for mictr01 tester vibrating string acquisition module development kit
Data connection mode in low code platform (Part 2)
Small game design framework
CTFshow,信息搜集:web4
Delete a whole page in word
Stm32cubemx, 68 sets of components, following 10 open source protocols
「2022年7月」WuKong编辑器更版记录
How does the database perform dynamic custom sorting?
Introduction and use of Kitti dataset
Decrypt the three dimensional design of the game
Attribute keywords ondelete, private, readonly, required
Cvpr2022 | backdoor attack based on frequency injection in medical image analysis
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Leetcode one question per day (636. exclusive time of functions)
MicTR01 Tester 振弦采集模塊開發套件使用說明
Niuke real problem programming - day14
Ian Goodfellow, the inventor of Gan, officially joined deepmind as research scientist
Summary on adding content of background dynamic template builder usage
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