[thread status, wait and wake-up, Lambda expression, Stream flow]

Posted by boske on Wed, 02 Mar 2022 01:29:30 +0100

day09 [thread status, wait and wake-up, Lambda expression, Stream flow]

Today's content

  • Multithreading
    • Thread status -------- -- > must be mastered
    • Waiting for wake-up mechanism -------- must be mastered
  • Lambda expression
    • Usage scenarios of Lambda expressions -------- -- > it is recommended to master
    • Format of Lambda expression (standard \ omitted) ---- > it is recommended to master
  • Stream stream
    • Overview of flow thinking
    • Using Stream -------- -- > it is recommended to master
      • Get flow – > operation flow – > collect results

Chapter 1 thread status

1.1 thread status

Thread status overview

The whole process of thread from birth to death: technical literacy and interview requirements.

The process from creation to destruction of a thread is called the thread life cycle. There are six states in the thread life cycle:

Thread stateCondition causing the state to occur
New (New)The thread has just been created but not started. The start method has not been called. MyThread t = new MyThread() has only thread objects and no thread characteristics. Error creating thread object
RunnableWhen the start() method is called, the thread may or may not be executing, depending on the scheduling of the operating system. When the start method is called
BlockedWhen a thread attempts to obtain a lock object and the lock object is held by another thread, the thread enters a lock blocking state; When the thread obtains the lock object, the thread will become runnable. Waiting for lock object
Waiting (unlimited waiting)When a thread is Waiting for another thread to perform a (wake-up) action, the thread enters the Waiting state. You cannot wake up automatically after entering this state. You must wait for another thread to call the notify or notifyAll method to wake up. When calling the wait() method
Timed waitingIn the same waiting state, several methods have timeout parameters. Calling them will enter the Timed Waiting state. This state will remain until the timeout period expires or a wake-up notification is received. A common method with timeout parameters is thread sleep ,Object.wait. When the sleep() method is called
TerminatedDie because the run method exits normally, or die because an uncapped exception terminates the run method. At the end of the run method execution

Thread state switching

We don't need to study the implementation principle of these states. We just need to know that such states exist in thread operation. How can we understand these States? It's easy to understand whether a thread is created or terminated. Let's study the transformation of a thread from a Runnable state to a non running state.

1.2 timed waiting and unlimited waiting

  • Timing and waiting: calling the sleep() method of the thread class can make the current thread enter the sleep state. When the sleep time is reached, the thread will be awakened automatically.

    • public static void sleep(long time) enables the current thread to enter a sleep state and automatically wake up after milliseconds to continue execution

      public class Test {
          public static void main(String[] args) throws InterruptedException {
              for (int i = 0; i < 100; i++) {
                  System.out.println("i Value of:"+i);
                  // Print once, pause for 3 seconds
                  Thread.sleep(3000);
              }
          }
      }
      
  • Infinite waiting

    • Method of Object class:

      • public void wait(): let the current thread enter the waiting state. This method must be called by locking the object
  • public void notify(): wakes up the thread waiting on the current lock object. This method must be called on the lock object

    • public void notifyAll(): wakes up all waiting threads on the current lock object. This method must be called by the lock object

    • Case 1: infinite waiting thread

      public class Test1 {
          // Lock object
          public static Object obj = new Object();
      
          public static void main(String[] args) {
              // Create and start thread -- > Enter infinite wait
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Infinite wait thread: Ready to enter infinite waiting...");
                      synchronized (obj) {
                          try {
                              obj.wait();// Enter infinite waiting
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System.out.println("Infinite wait thread:Wake up by another thread,And get the lock object,Continue execution...");
                      }
                  }
              }).start();
          }
      }
      
    • Case 2: wait and wake up case

      public class Test2 {
          // Lock object
          public static Object obj = new Object();
      
          public static void main(String[] args) throws InterruptedException {
              // Create and start thread -- > Enter infinite wait
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Infinite wait thread: Ready to enter infinite waiting...");
                      synchronized (obj) {// Lock
                          try {
                              obj.wait();// Enter infinite waiting
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System.out.println("Infinite wait thread:Wake up by another thread,And get the lock object,Continue execution...");
                      }// Release lock
                  }
              }).start();
      
              // In order to let the infinite waiting thread execute first, sleep before starting the wake-up thread
              Thread.sleep(100);
      
              // Create and start thread -- > wake up waiting thread
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Wake up thread:Prepare to wake up the infinite waiting thread");
                      synchronized (obj){
                          obj.notify();
                      }
                  }
              }).start();
      
              /*
                  Analysis procedure:
                      1.When the program enters the infinite waiting state, it will release the lock, release the cpu, and will not preempt again
                      2.The infinite wait thread is awakened. After getting the lock object, it will continue to execute from the position where it enters the infinite wait
               */
          }
      }
      
      

1.3 waiting for wake-up mechanism

What is the waiting wake-up mechanism

  • Overview: use wait and wake to realize regular execution among multiple threads
  • For example: the sub thread prints the i loop and the main thread prints the j loop
  • Do not use the wake-up waiting mechanism: the result is that the main thread and sub thread randomly alternate printouts ----- > irregular
  • Use the wake-up waiting mechanism: the results should be printed out regularly
    • Print 1 i cycle, then print 1 j cycle... Cycle print output in turn... --- > regular
    • How to achieve:
      • The sub thread prints an i-loop, then wakes up the main thread to execute, and enters an infinite wait
      • The main thread prints a j loop, then wakes up the sub thread to execute, and enters the infinite wait
      • The sub thread prints an i-loop, then wakes up the main thread to execute, and enters an infinite wait
      • The main thread prints a j loop, then wakes up the sub thread to execute, and enters the infinite wait
      • ...

How to implement the wake-up waiting mechanism:

  • 1. Use the lock object to call the wait() method to enter the infinite wait

  • 2. Use the lock object to call the notify() method to wake up the thread

  • 3. The lock objects of the call wait(),notify() method should be consistent

  • Case: the main thread and sub thread regularly alternate printouts

    public class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                synchronized (Test.lock) {
                    if (Test.flag == false){
                        // Infinite waiting
                        try {
                            Test.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                    if (Test.flag == true) {
                        System.out.println("Child thread i The value of is:" + i);
                        Test.lock.notify();
                        Test.flag = false;
                    }
                }
            }
        }
    }
    
    public class Test {
        // Lock object
        public static Object lock = new Object();
        // Switch variable --- flag variable
        public static boolean flag = false;// true: child thread execution false: main thread execution
    
        public static void main(String[] args) {
            // Requirements: the main thread and sub thread regularly alternate printouts
            // Create and start child threads
            new MyThread().start();
    
            // Tasks of the main thread
            for (int j = 0; j < 100; j++) {
                synchronized (lock) {
                    if (flag == true){
                        // Infinite waiting
                        try {
                            Test.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                    if (flag == false) {
                        System.out.println("Main thread j The value of is:" + j);
                        lock.notify();
                        flag = true;
                    }
                }
            }
    
            // result:
            // j-i-j-i-j-i-j....
        }
    }
    
    

Analyze the execution of the program waiting for wake-up mechanism

  • 1. Thread scheduling is preemptive regardless of whether the wake-up waiting mechanism is used
  • 2. When the thread enters the infinite wait, the thread will release the lock and the cpu will not compete again
  • 3. Wake up other threads. The current wake-up thread will not release the lock and the cpu will be
  • 4. The infinite wait thread is awakened. After getting the lock object, it will continue to execute from the position where it enters the infinite wait

1.4 waiting for wake-up cases

demand

  • The waiting wake-up mechanism is actually a classic problem of "producers and consumers".

  • Take the production of steamed stuffed buns and the consumption of steamed stuffed buns as an example. How can the waiting wake-up mechanism make effective use of resources:

analysis

Steamed stuffed bun shop thread production steamed stuffed bun,Finished production,There will be steamed stuffed buns,Wake up the food thread to eat steamed stuffed buns,Then the Baozipu thread enters the infinite wait;
Eat steamed stuffed bun,I'm full,There are no steamed stuffed buns,Wake up the baozi shop thread to produce baozi,Then the eating thread enters an infinite wait;
Steamed stuffed bun shop thread production steamed stuffed bun,Finished production,There will be steamed stuffed buns,Wake up the food thread to eat steamed stuffed buns,Then the Baozipu thread enters the infinite wait;
Eat steamed stuffed bun,I'm full,There are no steamed stuffed buns,Wake up the baozi shop thread to produce baozi,Then the eating thread enters an infinite wait;
.....
Steamed stuffed bun:
    state--->false:No steamed stuffed bun,ture:There are steamed stuffed buns
	filling
 Steamed stuffed bun shop thread:
	There are steamed stuffed buns,Enter infinite waiting
    The steamed stuffed bun is gone,Execute code(Production of steamed stuffed bun),Wake up other threads,Modify flag variable
 Eating thread:
    The steamed stuffed bun is gone,Enter infinite waiting
    There are steamed stuffed buns,Execute code(Eat steamed stuffed bun),Wake up other threads,Modify flag variable

realization

  • Steamed stuffed bun

    public class BaoZi {
        public String xian;
        public boolean flag;// The default value is false
    }
    
    
  • Steamed stuffed bun shop thread

    public class BaoZiPu extends Thread {
    
        BaoZi bz;
    
        public BaoZiPu(BaoZi bz) {
            this.bz = bz;
        }
    
        @Override
        public void run() {
            while (true) {
                synchronized (bz) {
                    // With the steamed stuffed bun, enter the infinite waiting
                    if (bz.flag == true){
                        try {
                            bz.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // When the package is gone, execute the code (produce the package), wake up other threads, and modify the flag variable
                    if (bz.flag == false){
                        System.out.println("Steamed stuffed bun shop thread:Start making steamed stuffed buns...");
                        bz.xian = "filling for dumplings made with chives and pork";
                        bz.flag = true;
                        bz.notify();
                        System.out.println("Steamed stuffed bun shop thread:The steamed stuffed bun is ready,Eat goods, come and eat steamed stuffed buns...");
                    }
    
                }
            }
        }
    }
    
    
  • Eating thread

    public class ChiHuo extends Thread {
    
        BaoZi bz;
    
        public ChiHuo(BaoZi bz) {
            this.bz = bz;
        }
    
        @Override
        public void run() {
            while (true) {
                synchronized (bz) {
                    // The steamed stuffed bun is gone. Enter the infinite waiting
                    if (bz.flag == false){
                        try {
                            bz.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // When the package is available, execute the code (eat the package), wake up other threads, and modify the flag variable
                    if (bz.flag == true){
                        System.out.println("Eating thread:Start eating steamed stuffed bun,Stuffing of steamed stuffed bun:"+bz.xian);
                        bz.flag = false;
                        bz.notify();
                        System.out.println("Eating thread:The steamed stuffed bun is finished,Steamed stuffed bun shop, come and make steamed stuffed buns========");
                    }
                }
            }
        }
    }
    
    
  • Test class

    public class Test {
        public static void main(String[] args) {
            // Create package sub object
            BaoZi bz = new BaoZi();// xian: null,flag: false
    
            // Create and start the package sub store thread
            new BaoZiPu(bz).start();
    
            // Create and start the feed thread
            new ChiHuo(bz).start();
        }
    }
    
    

Chapter 2 Lambda expression

2.1 overview of functional programming ideas

Object oriented programming idea

Object oriented emphasizes that objects "must do things in the form of objects". It is relatively complex. Sometimes we have to create an object just to do something, such as thread execution task. We have to create an interface object that implements Runnable, but what we really want is to pass the code in the run method to the thread object for execution

Function programming idea

In mathematics, a function is a set of calculation schemes with input and output, that is, "what to do with what". Relatively speaking, object-oriented overemphasizes that "things must be done in the form of objects", while functional thinking tries to ignore the complex object-oriented syntax - emphasizing what to do, not in what form. For example, when a thread executes a task, using functional thinking, we can pass a piece of code to the thread object for execution without creating a task object

2.2 experience of lambda expression

  • Create threads to execute tasks by implementing the Runnable interface

  • Anonymous inner class method to create threads to execute tasks

    • In fact, the above two methods pass tasks to threads for execution through Runnable implementation class objects
    • Thinking: is it possible to pass tasks to threads for execution without implementing class objects? - > Functional programming
  • Creating threads to execute tasks in Lambda mode

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("Passing tasks by implementing classes");
        }
    }
    
    
    public class Test {
        public static void main(String[] args) {
            // Create threads to execute tasks by implementing the Runnable interface
            MyRunnable mr = new MyRunnable();
            new Thread(mr).start();
    
            //Anonymous inner class method to create threads to execute tasks
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Passing tasks by anonymous inner classes");
                }
            }).start();
    
            //In fact, the above two methods pass tasks to threads for execution through Runnable implementation class objects
            // Thinking: is it possible to pass tasks to threads for execution without implementing class objects? --- > Functional programming
            // Functional programming: emphasize what to do, not in what form
    
            //Creating threads to execute tasks in Lambda mode
            new Thread(()->{System.out.println("Transfer tasks in the way of thinking of functional programming");}).start();
        }
    }
    
    
  • Lambda expressions have no special functions and are used to simplify code

2.3 standard format of lambda expression

  • standard format

    • Format: (parameter type, parameter name, parameter type, parameter name,...) - > {code block}
  • Prerequisites for the use of Lambda:

    • Only the interface with one abstract method in the interface can use Lambda expression

    • The interface with only one abstract method is called functional interface, which can be identified by @ FunctionalInterface annotation

    • eg:

      // A interface is a functional interface. You can use Lambda expression to replace the implementation class object
      public interface A{
          void method1();
      }
      // B interface is a functional interface. You can use Lambda expression to replace the implementation class object
      @FunctionalInterface
      public interface B{
          void method1();
      }
      
      // C interface is not a functional interface, so Lambda expressions cannot be used
      public interface C{
          void method1();
          void method2();
      }
      
      // D interface is a functional interface, which can replace the implementation class object with Lambda expression
      public interface D{
          void method1();
          default void method2(){
              
          }
          ...
      }
      
  • Format description

    • The parameter type, number and order in parentheses shall be consistent with the formal parameter list of the abstract method in the functional interface
    • ->Fixed format, indicating pointing
    • The content in braces is actually the method body of the abstract method in the interface rewritten before
  • Case demonstration

    • Runnable functional interface

      public class Test {
          public static void main(String[] args) {
              // -Runnable functional interface
              new Thread(() -> {
                  System.out.println("Task code");
                  System.out.println("Task code");
                  System.out.println("Task code");
                  System.out.println("Task code");
              }).start();
          }
      }
      
      
    • Comparator functional interface

      public class Test {
          public static void main(String[] args) {
              // -Comparator functional interface
              ArrayList<Integer> list = new ArrayList<>();
              list.add(500);
              list.add(100);
              list.add(400);
              list.add(200);
              list.add(300);
              // Sort -- > ascending sort
              Collections.sort(list, (Integer i1, Integer i2) -> {
                  return i1 - i2;
              });
              System.out.println("Sorted collection:" + list);
      
              // Sort -- > descending sort
              Collections.sort(list,(Integer o1,Integer o2)->{
                  return o2 - o1;
              });
              System.out.println("Sorted collection:" + list);
      
          }
      }
      
      
  • Lambda uses routine

    • 1. Judge whether Lambda expression can be used in this position - > use premise
    • 2. If it can be used, directly write () - > {}
    • 3. Fill in the contents in parentheses - > the formal parameters of abstract methods in functional interfaces are consistent
    • 4. Fill in the content in braces - > rewrite the method body required by the functional interface abstract method

2.4 omission format of lambda expression

  • Omission rule

    • Parameter types in parentheses can be omitted without writing
    • If there is only one parameter in the parentheses, the parentheses can also be omitted
    • If there is only one statement in braces, braces, return keyword and semicolon can also be omitted (the three should be omitted together)
  • Case demonstration

    public class Test {
        public static void main(String[] args) {
            // -Runnable functional interface
            // standard format 
            new Thread(() -> {
                System.out.println("Task code 1");
            }).start();
    
            // Omit format
            new Thread(() -> System.out.println("Task code 2")).start();
    
            // -Comparator functional interface
            ArrayList<Integer> list = new ArrayList<>();
            list.add(500);
            list.add(100);
            list.add(400);
            list.add(200);
            list.add(300);
            // Sort -- > ascending sort
            // Standard format:
            /*Collections.sort(list, (Integer i1, Integer i2) -> {
                return i1 - i2;
            });*/
    
            // Omit format:
            Collections.sort(list, ( i1,  i2) -> i1 - i2);
            System.out.println("Sorted collection:" + list);
    
            // Sort -- > descending sort
            // Omit format:
            Collections.sort(list,( o1, o2)-> o2 - o1);
            System.out.println("Sorted collection:" + list);
        }
    }
    
    

2.5 manifestations of lambda

  • Expression form of Lambda: where will Lambda expressions appear

    • Variable form: assign a Lambda expression

      public class Test {
          public static void main(String[] args) {
              // -Variable form:
              Runnable r1 = new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Runnable Anonymous Inner Class --Implementation class object");
                  }
              };
      
              Runnable r2 = () -> {
                  System.out.println("Runnable Corresponding Lambda expression");
              };  
          }
      }
      
      
    • Parameter form: pass in a Lambda expression as an argument

      public class Test {
          public static void main(String[] args) {
      
              Runnable r2 = () -> {
                  System.out.println("Runnable Corresponding Lambda expression");
              };
      
              // -Parameter form:
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("Runnable Anonymous Inner Class --Implementation class object");
                  }
              }).start();
      
              new Thread(() -> {
                  System.out.println("Runnable Corresponding Lambda expression");
              }).start();
              new Thread(r2).start();
      
          
          }
      }
      
      
    • Return value form: returns a Lambda expression (return value)

      public class Test {
          public static void main(String[] args) {
              // -Return value form:
              // -Comparator functional interface
              ArrayList<Integer> list = new ArrayList<>();
              list.add(500);
              list.add(100);
              list.add(400);
              list.add(200);
              list.add(300);
              Comparator<Integer> comp = getComparator();
              Collections.sort(list, comp);
              System.out.println("After sorting:" + list);
          }
      
          public static Comparator<Integer> getComparator() {
              /*return new Comparator<Integer>() {
                  @Override
                  public int compare(Integer o1, Integer o2) {
                      return o2 - o1;
                  }
              };*/
      
              //return (Integer o1, Integer o2)->{return o2 - o1;};//  standard format 
              return ( o1,  o2)-> o2 - o1;// Omit format
          }
      }
      
      

Chapter III Stream

In Java 8, thanks to the functional programming brought by Lambda, a new concept of Stream is introduced to solve the existing disadvantages of the existing collection class library.

3.1 feel the Stream

  • Traditional operation set

    • Requirements:

       List<String> one = new ArrayList<>();
              one.add("Delireba");
              one.add("Song Yuanqiao");
              one.add("Su Xinghe");
              one.add("Laozi");
              one.add("Zhuangzi");
      		one.add("Huang Qilong");
              one.add("grandson");
              one.add("master hongqi");
      demand:
      1. The names of the members of the team whose names are only three words;
      2. After screening, only the first three people in the team;
      
  • Stream stream operation collection

    public class Test {
        public static void main(String[] args) {
            List<String> one = new ArrayList<>();
            one.add("Delireba");
            one.add("Song Yuanqiao");
            one.add("Su Xinghe");
            one.add("Laozi");
            one.add("Zhuangzi");
            one.add("Huang Xiaoming");
            one.add("grandson");
            one.add("master hongqi");
            // Requirements:
            // 1. The names of the members of the team whose names are only three words;
            // 1.1 create a new set to store names with 3 characters
            ArrayList<String> list1 = new ArrayList<>();
    
            // 1.2 loop through this set
            for (String name : one) {
                // 1.3 in the cycle, judge, filter and store
                if (name.length() == 3){
                    list1.add(name);
                }
            }
    
            // 2. After screening, only the first three people in the team;
            // 2.1 create a new set to store the first three
            ArrayList<String> list2 = new ArrayList<>();
    
            // 2.2 cycle through 3 times and store
            for (int i = 0; i < 3; i++) {
                String e = list1.get(i);
                list2.add(e);
            }
    
            System.out.println("list2:"+list2);// list2: [song Yuanqiao, Su Xinghe, Huang Xiaoming]
    
            // Stream stream: get stream -- > operation stream (filter) - > get result 
            one.stream().filter(name->name.length()==3).limit(3).forEach(name->System.out.println(name));
        }
    }
    
    

3.2 overview of streaming ideas

  • Overview: flow thinking can be compared to the assembly line \ River in the factory workshop

  • characteristic:

    • Flow must build a complete function model, and there must be a termination method in the function model
    • Stream stream cannot be operated repeatedly, that is, a stream stream can only be used once
    • Stream streams do not store data
    • Stream streams do not modify the data source

3.3 access flow method

  • Get stream according to collection - > collection there is a method to get stream in the collection public default stream < E > stream();

    • Get stream from Collection

      public class Test1_according to Collection Collection fetch stream {
          public static void main(String[] args) {
              // List
              List<String> list = new ArrayList<>();
              list.add("Wang Baoqiang");
              list.add("Jia Nailiang");
              list.add("Nicholas Tse");
              list.add("Chen Yufan");
              // Get stream
              Stream<String> stream1 = list.stream();
      
              // Set
              Set<String> set = new HashSet<>();
              set.add("Ma Rong");
              set.add("Li Xiaolu");
              set.add("Cecilia Cheung");
              set.add("Bai Baihe");
              // Get stream
              Stream<String> stream2 = set.stream();
          }
      }
      
      
    • Get flow according to Map

      • Get the stream according to the key of the Map collection

      • Gets the stream based on the value of the Map collection

      • Get the flow of the object according to the key value of the Map collection

        public class Test2_according to Map Collection fetch stream {
            public static void main(String[] args) {
                Map<String,String> map = new HashMap<>();
                map.put("Wang Baoqiang","Ma Rong");
                map.put("Jia Nailiang","Li Xiaolu");
                map.put("Nicholas Tse","Cecilia Cheung");
                map.put("Chen Yufan","Bai Baihe");
                
                // -Get the stream according to the key of the Map collection
                Stream<String> stream1 = map.keySet().stream();
                
                //-Gets the stream based on the value of the Map collection
                Stream<String> stream2 = map.values().stream();
                
                //-Get the flow of the object according to the key value of the Map collection
                Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();
            }
        }
        
  • Get Stream from array ----- > static of method using Stream stream Stream

    • public static <T> Stream<T> of(T... values);

      public class Test3_Get stream from array {
          public static void main(String[] args) {
              String[] arr = {"Wang Baoqiang",
                      "Jia Nailiang",
                      "Nicholas Tse",
                      "Chen Yufan"};
              // Get stream from array element
              Stream<String> stream1 = Stream.of(arr);
              
              // Direct value transfer acquisition stream
              Stream<String> stream2 = Stream.of("Wang Baoqiang", "Jia Nailiang", "Nicholas Tse", "Chen Yufan");
          }
      }
      
      

3.4 common methods of stream flow

  • Termination method: the return value type of the method is not a Stream. There must be a termination method in the Stream, otherwise it cannot be executed

  • Deferred method: the return value type of the method is Stream

  • Common methods:

    • forEach: process the elements in the stream one by one

      public class Test1_forEach {
          public static void main(String[] args) {
              /*
                  forEach:
                      void forEach(Consumer<? super T> action);Process the elements in the stream one by one
                      Parameter Consumer: functional interface
               */
      
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Nicholas Tse", "Chen Yufan");
              // Requirements: output all elements in the flow separately
              //stream. forEach((String t)->{System.out.println(t);});//  standard format 
              stream.forEach(t -> System.out.println(t));// Omit format
          }
      }
      
      
    • count: counts the number of elements in the stream

      public class Test2_count {
          public static void main(String[] args) {
              /*
                  forEach:
                      long count();Count the number of elements in the stream
               */
      
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Nicholas Tse", "Chen Yufan");
              // Requirements: output all elements in the flow separately
              long count = stream.count();
              System.out.println("stream Number of stream elements:"+count);
          }
      }
      
      
    • Filter: filter according to conditions

      public class Test3_filter {
          public static void main(String[] args) {
              /*
                  filter:
                       Stream<T> filter(Predicate<? super T> predicate); Filter according to the specified conditions, and the elements that meet the conditions form a new Stream and return a new Stream stream
                       Parameter predict: functional interface ---- > is used for judgment
               */
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang","Lao Wang next door", "Nicholas Tse", "Wang Xiaoer", "Chen Yufan");
              // Requirement: filter out the elements surnamed Wang and print out
              stream.filter((String t)->{return t.startsWith("king");}).forEach(e->System.out.println(e));
          }
      
      }
      
      
    • limit: get the first few elements in the stream

      public class Test4_limit {
          public static void main(String[] args) {
              /*
                  limit:
                       Stream<T> limit(long maxSize); Take the first few elements
                      be careful: 
                          1.In general, the parameter is set to be greater than 0 and less than the number of elements in the flow
                          2.If the parameter setting is less than 0, an exception will be reported
                          3.If the parameter is set to 0, there are no elements in the returned stream
                          4.If the parameter setting is greater than the number of elements in the flow, the returned flow contains all the elements in the flow
               */
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang","Lao Wang next door", "Nicholas Tse", "Wang Xiaoer", "Chen Yufan");
              // Requirement: take the first four elements and print out
              stream.limit(4).forEach(e-> System.out.println(e));
              //stream. limit(9). forEach(e-> System.out.println(e));//  Fetch all elements in the stream
              //stream. limit(-9). forEach(e-> System.out.println(e));//  Report IllegalArgumentException exception
          }
      }
      
      
    • Skip: skip the first few elements in the stream

      public class Test5_skip {
          public static void main(String[] args) {
              /*
                  skip:
                      Stream<T> skip(long n);Skip the first few elements
                      be careful:
                          1.The parameter is generally set to be greater than 0 or less than the number of elements
                          2.If the parameter is set to 0, the returned new stream contains all elements
                          3.If the parameter is set to be greater than or equal to the number of elements, no elements are returned in the new stream
                          4.If the parameter is set to less than 0, an exception is reported
              */
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang","Lao Wang next door", "Nicholas Tse", "Wang Xiaoer", "Chen Yufan");
              // Requirements: skip the first four elements and print out the remaining elements
              stream.skip(4).forEach(e-> System.out.println(e));
              //stream. skip(8). forEach(e-> System.out.println(e));//  No element output
              //stream. skip(-8). forEach(e-> System.out.println(e));//  Report exception
      
          }
      }
      
    • map: mapping \ transformation

      public class Test6_map {
          public static void main(String[] args) {
              /*
                  map:
                      <R> Stream<R> map(Function<? super T, ? extends R> mapper); Convert elements of type T in the stream to elements of type R, and return a new stream (R)
                      be careful:
                          1.T,R The types of can be consistent or inconsistent
                          2.Parameter Function: functional interface -- > conversion interface
               */
              // Get stream
              Stream<String> stream = Stream.of("100", "200", "300", "400", "500");
              // Requirements: convert the string type in the stream to Integer type and print out
              stream.map((String t)->{return Integer.parseInt(t);}).forEach(e-> System.out.println(e+1));
      
          }
      }
      
    • concat: splice 2 streams

      public class Test7_concat {
          public static void main(String[] args) {
              /*
                  concat:
                      public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) Splice the elements in the two streams to get a new stream
               */
              // Get stream
              Stream<String> stream1 = Stream.of("100", "200", "300", "400", "500");
              // Get stream
              Stream<String> stream2 = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang","Lao Wang next door");
              // Splicing
              Stream.concat(stream1,stream2).forEach(e-> System.out.println(e));
      
          }
      }
      
      
    • ...

3.5 Stream comprehensive case

demand

Now there are two ArrayList collections to store the names of multiple members in the team. It is required to use the Stream stream Stream. Carry out the following steps in sequence:

  1. The first team only needs the name of the member whose name is three words;
  2. After the first team is screened, only the first three people;
  3. The second team only needs the names of members surnamed Zhang;
  4. After the second team is screened, do not use the first two people;
  5. Merge the two teams into one team;
  6. Create a Person object based on the name;
  7. Print the Person object information of the whole team.

The codes of the two teams (sets) are as follows:

public class DemoArrayListNames {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("Delireba");
        one.add("Song Yuanqiao");
        one.add("Su Xinghe");
        one.add("Laozi");
        one.add("Zhuangzi");
        one.add("grandson");
        one.add("master hongqi");

        List<String> two = new ArrayList<>();
        two.add("Gulinaza");
        two.add("zhang wuji");
        two.add("Zhang Sanfeng");
        two.add("Zhao Liying");
        two.add("Zhang Ergou");
        two.add("Zhang Tianai");
        two.add("Zhang San");
		// ....
    }
}

realization

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("Delireba");
        one.add("Song Yuanqiao");
        one.add("Su Xinghe");
        one.add("Laozi");
        one.add("Zhuangzi");
        one.add("grandson");
        one.add("master hongqi");

        List<String> two = new ArrayList<>();
        two.add("Gulinaza");
        two.add("zhang wuji");
        two.add("Zhang Sanfeng");
        two.add("Zhao Liying");
        two.add("Zhang Ergou");
        two.add("Zhang Tianai");
        two.add("Zhang San");

        // 1. The first team only needs the name of the member whose name is three words;
        // 2. After the screening of the first team, only the first three people;
        Stream<String> stream1 = one.stream().filter((String t) -> {
            return t.length() == 3;
        }).limit(3);

        // 3. The second team only needs the names of members surnamed Zhang;
        // 4. After the second team is screened, do not use the first two people;
        Stream<String> stream2 = two.stream().filter((String t) -> {
            return t.startsWith("Zhang");
        }).skip(2);

        // 5. Merge the two teams into one team;
        // 6. Create a Person object according to the name;
        // 7. Print the Person object information of the whole team.
        Stream.concat(stream1,stream2).map((String name)->{ return new Person(name);}).forEach(p-> System.out.println(p));
        
    }
}

3.6 collect Stream results

Collect into array

  • public statci Object[] toArray(); Collect the elements in the stream into an array

    public class Test1_Collect into array {
        public static void main(String[] args) {
            // Get stream
            Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang","Lao Wang next door", "Nicholas Tse", "Wang Xiaoer", "Chen Yufan");
            // Requirement: filter out the elements surnamed Wang and collect the results into the array
            Object[] arr = stream.filter(name -> name.startsWith("king")).toArray();
            for (Object o : arr) {
                System.out.println(o);
            }
        }
    }
    
    

Collect into collection

  • <R, A> R collect(Collector<? super T, A, R> collector); Collect the elements in the stream into a collection

    • R: Return value type, that is to say, the type of R is what kind of collection is returned

    • The generic R in the parameter Collector determines the return value type of the method

    • How to get the Collector??? ----- > Tool class Collectors

      • public static <T> Collector<T, ?, List<T>> toList()
      • public static <T> Collector<T, ?, Set<T>> toSet()
      • eg; stream.collect(Collectors.toList()) collects the List collection
      • eg: ``stream.collect(Collectors.toSet()) collects the Set`
      public class Test1_Collect into collection {
          public static void main(String[] args) {
              // Get stream
              Stream<String> stream = Stream.of("Wang Baoqiang", "Jia Nailiang", "Uncle Wang", "Lao Wang next door", "Nicholas Tse", "Wang Xiaoer", "Chen Yufan");
              // Requirement: filter out the elements surnamed Wang and collect the results into the collection
              //List<String> list = stream. Filter (name - > name. Startswith ("King")) collect(Collectors.toList());
              //System.out.println("list:" + list);
      
              Set<String> set = stream.filter(name -> name.startsWith("king")).collect(Collectors.toSet());
              System.out.println("set:" + set);
          }
      }
      

summary

Must practice:
	1.Switching between six states of thread----->Draw a picture
    2.Wait for wake-up mechanism--->How to implement the wake-up waiting mechanism,How to analyze the execution process of waiting for wake-up mechanism cases
        2.1 Regular printing i Cycle and j loop
        2.2 Case of eating steamed stuffed bun
    3.Lambda expression: 
		3.1 Dictation use Lambda Expression routines---->4 step
        3.2 Premise of dictation
        3.3 Dictation ellipsis rule
    4.Stream flow:
		Comprehensive case---->Collect the results into an array or collection
            
- Be able to name the six states of the thread
    newly build,Operable,Lock blocking,Infinite waiting,Timed waiting ,Be terminated
            
- Be able to understand the case of waiting for wake-up
  How to implement the wake-up waiting mechanism:
    - 1.Call with lock object wait()Method enters infinite wait
    - 2.Call with lock object notify()Method wakes up the thread
    - 3.call wait(),notify()The lock objects of methods should be consistent
  Analyze the execution of the program waiting for wake-up mechanism
    - 1.Whether wake-up waiting mechanism is used or not,Thread scheduling is preemptive
    - 2.Thread enters infinite wait,The thread releases the lock,cpu,And won't compete again
    - 3.Wake up other threads,The current wake-up thread will not release the lock,cpu of
    - 4.Infinite wait for the thread to wake up,After getting the lock object,It will continue to execute from the position of entering infinite waiting
  
   
- Can grasp Lambda Standard and omitted forms of expressions
   Lambda Use routine
    - 1.Judge whether it can be used in this position Lambda expression--->Use premise
    - 2.If available,Write it directly()->{}
    - 3.Fill in parentheses--->The formal parameters of abstract methods in functional interfaces are consistent
    - 4.Fill in braces--->Override the method body required by the functional interface abstract method
  Omission rule
    - Parameter types in parentheses can be omitted without writing
    - There is only one parameter in parentheses,Then parentheses can also be omitted
    - If there is only one statement in braces,So braces,return keyword,Semicolons can also be omitted(The three should be omitted together)
  Use premise: Functional interface

- The stream can be obtained by collection, mapping or array
   use Collection of stream method
   use Stream Flowing of method
      
- Be able to master common flow operations
   forEach,count,filter,limit,skip,concat,map
- It can collect the contents of the stream into collections and arrays
  Object[] toArray();
  stream.collect(Collectors.toList()) Collected List aggregate
  stream.collect(Collectors.toSet()) Collected Set aggregate

Topics: Java Lambda Interview Multithreading