main idea
- Using methods and Lambda as first-class values, and when there is no variable shared state, functions or methods can be executed in parallel efficiently and safely
Method behavior parameterization
- The concrete parameterization is abstract. The behavior of a method depends on the code passed through the interface object parameters, that is, the interface is used as a part of the method parameters. Different implementation classes of the interface can provide different methods. Such interface parameters greatly enhance the flexibility and extensibility of the method.
Functional interface
-
Definition: There is only one abstract method in the interface (optional interface annotation, @FunctionInterface)
- Even if other
default
modified default methods are defined , the interface is also a functional interface.
- Even if other
-
advantage
- It is not necessary to explicitly declare many classes that only need to be instantiated once. Java8 could previously use
匿名类
declarative to implement such a code
- It is not necessary to explicitly declare many classes that only need to be instantiated once. Java8 could previously use
-
effect
-
The functional interface can be assigned a variable.
Runnable r1 = () -> System.out.println("Hello World!");
-
Pass to a method that accepts a functional interface as a parameter.
-
Lambda expression principle
-
Lambda expressions can generate an instance of a functional interface (you don't have to write a lot of template code like internal classes)
-
The Lambda expression itself does not contain which functional interface it is implementing. The type of interface implemented is inferred from the context in which the Lambda is used. The context (for example, accepts the parameters of the method it passes or the local variables that accept its value,
即在Lambda表达式用到的参数推断,或表达式结果值的类型推断出接口函数的类型
) The type required in the Lambda expression (which functional interface) is called目标类型
. Inferring which functional interface can be used to derive this type函数描述符(即函数式接口中抽象方法的签名,形如T->boolean或T->R)
, any actual parameters of the method that finally contains the Lambda expression must match目标类型及对应的函数描述符
Method reference
Streams and collections
- difference
- A collection is a data structure in memory that contains all the current values in the data structure-each element in the collection must be calculated before it can be added to the collection. (You can add or delete things to the collection, but no matter when, each element in the collection is placed in memory, the elements must be calculated before they can become part of the collection.)
- In contrast, streams are conceptually fixed data structures (you cannot add or delete elements), and their elements are calculated on demand. A stream is like a collection created late: the value is calculated only when requested by the consumer. On the contrary, the collection is created eagerly
-
Stream operation will be automatically closed after one
- The same stream can only be used once, and once consumed, it is consumed. You need to re-create the stream if you want to spread it again.
- It is necessary to store all of them in memory before the operation of the collection, which can be repeated many times. But it is slow and consumes memory resources.
-
Internal iteration (flow) External iteration (collection)
- Intermediate operation and terminal operation
- Intermediate operation returns a stream
- Terminal operations process incoming streams and return values that are not streams
Use stream
-
Screening and slicing
- Filter stream, filter (Predicate
p) - To deduplicate the stream, distinct () implements the stream based on the hashCode and equals methods of the elements generated by the stream.
- Truncate the stream, limit ()
- Skip elements, skip ()
- Filter stream, filter (Predicate
-
Map
-
map
-
Key extractor
-
flatMap
-
Flatten the multi-dimensional flow into one dimension, that is, multiple flows into one
-
Arrays.stream () converts other streams to array streams
-
-
Optional
class - (Java.util.Optional) is a container class that represents the presence or absence of a value. Avoid bugs related to null check, that is, return null is allowed
-
Find and match
- Match at least one, anyMatch (Predicate
p) - Match all, allMatch (Predicate
p) - contain. findAny (), with Optional
Used together, returns true immediately if it contains one - Find the first one. findFirst ()
- Match at least one, anyMatch (Predicate
-
Reduction: combine all elements in a stream to get a value
- Sum. reduce (initial value, BinaryOperator
), The descriptor of the function interface (T,T)->R
, there is a new static sum method sum in Integer,reduce(0,Integer::sum)
- Overloaded. The overloaded variant of reduce does not accept the initial value and returns an Optional object. Optional
sum = numbers.stream().reduce((a, b) -> (a + b)); )))) - Find the maximum / minimum value.
Optional<Integer> sum = numbers.stream().reduce(Integer::max);
Optional<Integer> sum = numbers.stream().reduce(Integer::min)
- Sum. reduce (initial value, BinaryOperator
Numerical flow
-
Conversion of packaging type flow to original type (mapped to numeric flow)
mapToInt()/mapToDoubld()/mapToLong()
These methods convertStream<T>
types of streams into correspondingint/double/long
-
Conversion of original type flow to packaging type (conversion back to object flow)
intStream.boxed()
-
Value range
- IntStream.rangeClosed (1,100), contains 100; IntStream.range (1,100) does not contain 100
Build stream
-
Create stream from value
Stream.of()
Convert any number of parameters into a streamStream.empty()
Create an empty stream
-
Create from array
Arrays.stream(T[])
Pass in any type of array, will return a stream object
-
Generate stream from file
- Files.lines, it will return a string stream consisting of the lines in the specified file. You can use Files.lines to get a stream, where each element is a line in a given file.
-
Have function to generate stream: create infinite stream
- Iterate.
Stream.iterate(初始值,UnaryOperator<T>)
,依次
Which is an infinite and unbounded stream, which needs to be limited by limit (). - Application: Use when you need to generate a series of values in sequence; generate a Fibonacci sequence
Stream.iterate(new int[]{0,1},t-> new int[]{t[1],t[0]+t[1]}) .limit(20) .map(t->t[0]) .forEach(System.out::println);
- generate.
Stream.generate(Supplier<T>)
Generate an infinite stream on demand, stateful, avoid using in parallel - application. Generate random numbers.
Stream.generate(Math::random) .limit(5) .forEach(System.out::println);
- Iterate.
collector
-
Definition: When the stream items need to be reassembled into a collection, a collector (the parameter of the Stream method collect) is generally used. It can be used whenever you want to merge all the items in the stream into one result. This result can be of any type, can be as complex as a multi-level map representing a tree, or as simple as an integer
-
The relationship between collect and Collector interfaces and Collectors
-
The call
collect
method on the stream triggers a reduction operation on the elements in the stream (parameterized by the Collector). Generally speaking, the Collector applies a conversion function to the element (in many cases, it is an identity conversion that does not reflect any conversion effect, such as toList).Collector
The implementation in the interface determines how to perform归约
operations on the stream怎样的收集器实例
, and theCollectors
utility class provides many more static factory methods, you can方便的创建常见收集器的实例
.
Reduction and aggregation (predefined collectors in Collectors)
-
Find the maximum and minimum values in the stream
Collectors.maxBy(Comparator<T>)
AndCollectors.minBy(Comparator<T>)
return the most valuable collector instance
-
Counting (Collectors can be omitted, the methods called are all static methods that return Collectos instances)
collect(Collectors.counting())
collect(Collectors.summinInt(Function<T,R> f)
Receive a function that maps the object to the int required for summation, the parameter Function is a conversion function, the same belowcollect(Collectors.averagingInt(Function<T,R> f))
Averagecollect(Collectors.summarizingInt())
Returns the maximum / smallest value and average value of the conversion function, the sum
-
Connection string
collect(Collectors.join())
The collector returned by the joining factory method will concatenate all the strings obtained by applying the toString method to each object in the stream into a string, and internally uses StringBuilder to add the generated strings one by one.collect(Collectors.join(","))
The overloaded version of the joining factory method, each stringdelimiter
is separated and combined into a string by a specified delimitercollect(Collectors.join(",","(",")"))
The overloaded version of the joining factory method,,
separating each string with and then combining them into a string, and appending prefixesprefix (
and suffixes to the head and tail of the combined stringsuffix )
Grouping (Java8 functional style)
-
First-level grouping
collect(Collector.groupingBy(Function))
, A function (in the form of a method reference) is passed to the groupingBy method. The function is called a classification function because it is used to divide the elements in the stream into different groups. The value returned by the grouping function is used as the mapping key, and the list of all items with this classification value in the stream is used as the corresponding mapping value.
-
Two-level grouping (multi-level grouping)
collect(groupingBy(Function),groupingBy(Function))
The key of the outer Map is the value generated by the first-level classification function, and the value of this Map is a new Map, where the key of the new Map is the value generated by the second-level classification function, and the value of the second-level map is the element in the stream The formed List is the value of the corresponding first-level and second-level keys obtained by applying the first-level and second-level classification functions respectively
Partitioning (partitioningBy)
- Partitioning is a special case of grouping: a predicate (a function that returns a Boolean value) is used as a classification function, which is called a partitioning function. The partition function returns a Boolean value, which means that the key type of the resulting grouped map is Boolean, so it can be divided into two groups at most-true is one group and false is one group.