[toc]
java8 combat learning
1. lambda expressions
1.1 What is a lambda expression
1.2 What kind of scenarios can use lambda expressions
1.3 Four ways to write a lambda expression to implement an interface
2. Functional programming
2.1 What is functional programming
2.2 What is imperative programming
2.3 What is FunctionalInterface
2.4 What is the default method
2.5 The meaning of the default method
2.6 Common functional interfaces built in java8
(1). Predicate<T>
assert -> input T, output boolean
(2).Consumer<T>
Consume an input -> input T, no output (void)
(3).Supplier<T>
produce an output -> no input, output T
(4).Function<T, R>
A function of input T, output R
(5).UnaryOperator<T>
Unary function: 1 input and 1 output: all types are T
(6).BinaryOperatior<T>
Binary function: 2 inputs and 1 output: both types are T
(7).BiFunction<T, U, R>
Input two outputs one: input T, U output R, often used for operations such as reduce/sort,
2.7 Method references
(1). Method reference of static method
(2). Method reference of instance method
(3). Method reference of constructor
2.8. Variable references and implicit final
Why inner classes use outer variables to be final
3. Stream programming
3.1. External and internal iterations
(1). What is external iteration
(2). What is internal iteration
3.2. Intermediate operations/termination operations/lazy evaluation
(1). What is an intermediate operation?
Operations that return or stream streams are intermediate operations, such as map operations
map
flatMap
distinct
limit
skip
filter
peek
sorted
(1.1) Stateful operations
Operations with sequential dependencies, such as
distinct
(can not be the same before and after)
sorted
(required before and after)
limit
/ skip
(cut off/skip previous)
(1.2) Stateless operation
Operations without pre- and post-dependencies:
map
/ mapToInt
/ flatMap
/ flatMapToInt
filter
peek
(2). What is the termination operation?
Returns a result (sum/aggregate) etc., such as sum/max/min/avg etc.
forEach
collect
reduce
toArray
min/max/count
findAny
findFirst
allMatch
anyMatch
noneMatch
(1.1) Short-circuit operation
findFirst
findAny
allMatch
anyMatch
noneMatch
(1.2) Non-short-circuit operation
forEach
forEachOrdered
guaranteed order in parallel stream
collect
toArray
reduce
input: BinaryOperator<T>
min
max
count
(3). What is lazy evaluation?
If there is no termination operation, the intermediate operation actions will not actually be executed, which is lazy evaluation;
3.3 Creation of stream
(1) Collection
collection.stream
collection.parallelStream
(2) Array
array.stream
Stream.of
(3). Numbers
IntStream
IntStream.range
IntStream.rangeClosed
LongStream
LongStream.range
LongStream.rangeClosed
Random
Random.longs
Random.ints
Random.doubles
(4). Create it yourself
Stream.generate
Stream.iterate
3.4 Parallel Streams
(1).parallel()
(2). The thread pool used by default for parallel streams
ForkJoinPool.commonPool
(3). Custom thread pool
How to customize the thread pool and use it when the stream is parallel?
3.5 Collector collect
(1). The property list of the collection object is a new collection
collect(Collectors.toList())
(2). Summary of statistical information
IntSummaryStatistics ageSumStats = students.stream().collect(Collectors.summarizingInt(Student::getAge))
(3). Block: use assertion (divided into two)
Map<Boolean, List<Student>> genders = students.stream().collect(Collectors.partitioningBy(s->s.getGender() == Gender.MALE))
(4). Grouping: use attributes (one is divided into N, similar to sql groupby)
Map<Grade, List<Student>> grades = students.stream().collect(Collectors.groupingBy(Student::getGrade))
(5). Group and aggregate counts
Map<Grade, Long> gradeCount = students.stream().collect(Collectors.groupingBy(Student::getGrade, Collectors.counting()));
counting() can be replaced with similar max/min/avg etc.
(6). Summary
Collectors.toList()
Collectors.toCollection()
Collectors.summarizingInt(x)
Collectors.partitioningBy(x)
Collectors.groupingBy(x)
Collectors.counting()
3.6 Stream operation mechanism
(1). Chain call
All operations are called in a chain, 1 element is only iterated once;
(2). Attribute sourceStage
Each intermediate operation returns a new stream, which has an attribute: sourceStage; points to the same place: the head of the linked list
(3). Head -> nextStage -> nextStage -> null
The implementation class of the stream interface
java.util.stream.AbstractPipeline
java.util.stream.ReferencePipeline
Properties: sourceStage --> ReferencePipeline$Head
(4). Stateless operation mechanism
Complete chain call: s1.a is finished -> s1.b
(5). Stateful operation mechanism
public void testStream() {
Random r = new Random();
Stream.generate(() -> r.nextInt()).limit(500)
.peek(s -> System.out.println("peek: " + s)) // 1
.filter(s -> { // 2
System.out.println("filter: " + s);
return s > 1000000;
})
.sorted((i1, i2) -> { // 3.
System.out.println("排序:" + i1 + ", " + i2);
return i1.compareTo(i2);
})
.peek(s -> System.out.println("peek2:" + s)) //4.
.count();
}
1, 2 are stateless operations; 3 are stateful operations; 4 are stateless operations
The stateful operation of 3 will truncate the stateless operation of 1 and 2;
Originally a chain call of 1, 2: s1.a->s1.b->s1.c now becomes: s1.a() ->s2.a() -> s1.b() ->s2 .b()
output: no sorted: you can see 纯无状态操作是纯链式: peek->filter->peek2
peek: 2047843427
filter: 2047843427
peek2:2047843427
peek: -1210662664
filter: -1210662664
peek: 835825054
filter: 835825054
peek2:835825054
peek: 2068471207
filter: 2068471207
peek2:2068471207
peek: -1139851578
filter: -1139851578
peek: -885776051
filter: -885776051
peek: 481902862
filter: 481902862
peek2:481902862
peek: 684461691
filter: 684461691
peek2:684461691
peek: 1417449012
filter: 1417449012
peek2:1417449012
peek: -40633821
filter: -40633821
output: sorted: 可以看到后面的无状态操作peek2被有状态的sorted打断, 变成: peek->filter... peek->filter 排序all, peek2 all
peek: -607778068
filter: -607778068
peek: 50926402
filter: 50926402
peek: -774310924
filter: -774310924
peek: 342023904
filter: 342023904
peek: 26606322
filter: 26606322
peek: 693727663
filter: 693727663
peek: -334751306
filter: -334751306
peek: -960784614
filter: -960784614
peek: 522967780
filter: 522967780
peek: -2144851449
filter: -2144851449
排序:342023904, 50926402
排序:26606322, 342023904
排序:26606322, 342023904
排序:26606322, 50926402
排序:693727663, 50926402
排序:693727663, 342023904
排序:522967780, 342023904
排序:522967780, 693727663
peek2:26606322
peek2:50926402
peek2:342023904
peek2:522967780
peek2:693727663
1, 2 are still chained calls; after the middle 3 is executed, 4 is cut off, so 4 will not continue the chained calls with 1,2, but will be executed separately;
(6) Parallel operation: parallel()
Add 5 after 4: parallel():
sorted()
Stateful operations will not be parallelized; 1, 2, and 4 will all be executed in parallel using the ForkJoinPool thread pool:
@Test
public void testStream() {
Random r = new Random();
long count = Stream.generate(() -> r.nextInt()).limit(10)
.peek(s -> System.out.println(Thread.currentThread().getName() + " peek: " + s)) // 1
.filter(s -> { // 2
System.out.println(Thread.currentThread().getName() + " filter: " + s);
return s > 1000000;
})
.sorted((i1, i2) -> { // 3.
System.out.println(Thread.currentThread().getName() + " 排序:" + i1 + ", " + i2);
return i1.compareTo(i2);
})
.peek(s -> System.out.println(Thread.currentThread().getName() + " peek2:" + s)) //4.
.parallel()
.count();
System.out.println(count);
}
ForkJoinPool.commonPool-worker-1 peek: -1644694686
ForkJoinPool.commonPool-worker-1 filter: -1644694686
ForkJoinPool.commonPool-worker-1 peek: 1524371421
ForkJoinPool.commonPool-worker-1 filter: 1524371421
ForkJoinPool.commonPool-worker-1 peek: -1937453784
ForkJoinPool.commonPool-worker-1 filter: -1937453784
ForkJoinPool.commonPool-worker-1 peek: 991114309
ForkJoinPool.commonPool-worker-1 filter: 991114309
ForkJoinPool.commonPool-worker-1 peek: -109655961
ForkJoinPool.commonPool-worker-1 filter: -109655961
ForkJoinPool.commonPool-worker-1 peek: 878490064
ForkJoinPool.commonPool-worker-1 filter: 878490064
ForkJoinPool.commonPool-worker-1 peek: 2031919515
ForkJoinPool.commonPool-worker-1 filter: 2031919515
ForkJoinPool.commonPool-worker-1 peek: -1855129379
ForkJoinPool.commonPool-worker-1 filter: -1855129379
ForkJoinPool.commonPool-worker-1 peek: 1897985020
ForkJoinPool.commonPool-worker-1 filter: 1897985020
ForkJoinPool.commonPool-worker-1 peek: 352116584
ForkJoinPool.commonPool-worker-1 filter: 352116584
main 排序:991114309, 1524371421
main 排序:878490064, 991114309
main 排序:2031919515, 878490064
main 排序:2031919515, 991114309
main 排序:2031919515, 1524371421
main 排序:1897985020, 1524371421
main 排序:1897985020, 2031919515
main 排序:352116584, 1524371421
main 排序:352116584, 991114309
main 排序:352116584, 878490064
ForkJoinPool.commonPool-worker-6 peek2:991114309
main peek2:1524371421
ForkJoinPool.commonPool-worker-3 peek2:352116584
ForkJoinPool.commonPool-worker-2 peek2:2031919515
ForkJoinPool.commonPool-worker-7 peek2:1897985020
ForkJoinPool.commonPool-worker-4 peek2:878490064
6
Conclusion: 有状态的并行操作"不一定"并行
why is "not necessarily"?
Because the official did not say it clearly, but after observation, it is non-parallel!
3.7 Summary Chain call principle:
- The principle of stream chain call: ReferencePipeline
- Each intermediate operation produces a stream (new stream)
- The relationship between the new stream and the original stream: There is a sourceStage->Head node pointing to the original stream in the new stream (ReferencePipeline$Head)
- Maintenance of chain calls: nextStage -> nextStage -> null in ReferencePipeline to maintain the chain;
3.8 Summary 2
- Stateful operations break chained calls
- Stateful operations in parallel operations are not necessarily parallel, such as sorting!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。