[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
Stream流继承关系

(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:

  1. The principle of stream chain call: ReferencePipeline
  2. Each intermediate operation produces a stream (new stream)
  3. 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)
  4. Maintenance of chain calls: nextStage -> nextStage -> null in ReferencePipeline to maintain the chain;

3.8 Summary 2

  1. Stateful operations break chained calls
  2. Stateful operations in parallel operations are not necessarily parallel, such as sorting!

丰木
322 声望19 粉丝

遇见超乎想象的自己!


引用和评论

0 条评论