Java knowledge point 03 - object oriented 02 (wrapper class, final keyword, abstract class, interface, internal class, Lambda, enumeration class, functional interface, Stream API)

Posted by Addos on Wed, 23 Feb 2022 14:31:34 +0100

Statement:

  1. The information comes from your own arrangement.
  2. Reference book crazy Java handout (Fifth Edition) Li Gang © Write

1, Packaging

1.1 general

   Java provides two type systems: basic type and reference type. Using basic type is efficient. However, in many cases, objects will be created for use, because objects can do more functions. If you want our basic type to operate like objects, you can use the wrapper class corresponding to the basic type, as follows:

Basic typeCorresponding wrapper class (in java.lang package)
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

1.2 packing and unpacking

The process of back and forth conversion between the basic type and the corresponding packing class object is called "packing" and "unpacking":

  • Packing: convert from basic type to corresponding packing class object.

  • Unpacking: convert from package object to corresponding basic type.

Take Integer and int as an example: (just understand the code)

Basic value ----- > packing object (packing)

Integer i = new Integer(3);//1. The constructor creates an instance of Integer type to realize automatic boxing
Integer i2 = Integer.valueOf(3);//2. Use the valueOf method in the wrapper class to create an instance of Integer type to realize automatic boxing

System.out.println(i == i2);// false / / two objects
System.out.println(i.equals(i2));//true / / the values are the same

Packing object ----- > basic value (unpacking)

//Automatic unpacking integer - > int
int i3 = i.intValue();
or
int i4 = new Integer(4);

1.3 automatic packing and unpacking

Since we often need to convert between basic types and packaging classes, the boxing and unpacking of basic types and packaging classes can be completed automatically from Java 5 (JDK 1.5). For example:

Integer i = 4;//Automatic packing. Equivalent to integer I = integer valueOf(4);
i = i + 5;//Right of the equal sign: convert the I object to the basic value (automatic unpacking) i.intValue() + 5;
//After the addition operation is completed, box again and convert the basic value into an object.

1.4 conversion between basic type and string

extend

  1. The basic type can be converted into a string by directly connecting it with ""; For example: 34 + "

2, final keyword

//1. Modified class (modified class cannot be inherited)
final class Class name {

}
// Query API and find public final class String, public final class Math, public final class Scanner, etc,
// Many of the classes we've learned are modified by final. The purpose is for us to use them without changing their contents

//2. Modification method: rewrite the method modified by final, and an error will be reported during compilation.
Modifier  final Return value type method name(parameter list){
		//Method body
}

//3. Modify variables
	1)Local variable - Basic Type: local variable of basic type, which is final After modification, it can only be assigned once and cannot be changed. The code is as follows:
    /**
     * 1.Once a member variable has an initial value, it cannot be reassigned
     * 2.final Decorated member variables must have an initial value explicitly specified by the programmer
     * 3.final Decorated member variable (one out of three)
     *      (1)Or initialize when defining variables,
     *      (2)Either initialize in a normal initialization block,
     *      (3)Either initialize in the constructor
    */
      public class FinalDemo1 {
          public static void main(String[] args) {
              // Declare variables and use final modification
              final int a;
              // First assignment
              
              a = 10;
              // Second assignment
              a = 20; // An error is reported and cannot be re assigned
              // Declare variables, assign values directly, and use final modification
              final int b = 10;
              // Second assignment
              b = 20; // An error is reported and cannot be re assigned
          }
      }
      
	2)local variable--Reference type: local variable of reference type, which is final After modification, you can only point to one object, and the address cannot be changed. However, it does not affect the modification of the member variable value inside the object. The code is as follows:
      public class FinalDemo2 {
          public static void main(String[] args) {
              // Create User object
              final User u = new User();
              // Create another User object
              u = new User(); // An error is reported, pointing to a new object, and the address value changes.
              // Call setName method
              u.setName("Zhang San"); // Can be modified
          }
      }
      
	3)Member variable: member variable involves initialization. There are three initialization methods, and only one of them can be selected:
    //Note: the constant names modified by final are generally written in a standard way, and all letters are capitalized.
    	1.Display initialization
    		public class User {
                 final String USERNAME = "Zhang San";
                 private int age;
			}

		2.constructor initialization 
        public class User {
            final String USERNAME ;
            private int age;
            
            public User(String username, int age) {
                this.USERNAME = username;
                this.age = age;
            }
        }
        
		3.Initialization in normal initialization block
        public class User{
            final String USERNAME;
            {
                USERNAME = "zhangsan";
            }
        }

3, abstract class


4, interface

4.1 Interface Overview

   Java interface is a declaration of a series of methods and a collection of method features. An interface has only method features and no method implementation. Therefore, these methods can be implemented by different classes in different places, and these implementations can have different behaviors (functions).

4.2 definition format

⚠️ be careful:

  1. In the interface, member variables cannot be defined, but constants can be defined, and their values cannot be changed. public static final is used by default.
  2. There is no constructor in the interface, so the object cannot be created.
  3. There is no static code block in the interface.
public interface Interface name {
    //Constants (only those modified by public static final) for example:
    public static final int MAX_INT = 3;	//Abbreviation: int MAX_INT = 3;
    
    // Abstract method / / the abstract method (without method body) in the interface that the subclass must implement, for example:
    public abstract void abstractMethod(); //Abbreviated as void abstractMethod();
    
    // Default method / / subclasses can inherit and override the default method. For example:
    default void defaultMethod(){}
    
    // Static methods / / can only be invoked in this interface, for example:
    static String staticMethod(){}
    
    // Private method 	// It is mainly used as a tool method to support the default methods in the interface, such as:
    private void privateMethod(){}
    
    //Static private method / / for example:
    prvate static void privateMethod(){}
}

4.3 basic realization

   the relationship between class and interface is implementation relationship, that is, class implements interface. This class can be called implementation class of interface or subclass of interface. The actions implemented are similar to inheritance and the format is similar, but the keywords are different. The implementation uses the implements keyword.

Non Abstract subclass implementation interface:

  1. You must override all abstract methods in the interface.
  2. Inherits the default method of the interface, which can be called directly or overridden.

[format]

class Class name implements Interface name {
	// Rewrite the abstract method in the interface [required]
	// Override the default method in the interface [optional]
}

4.4 multiple implementations and inheritance of interfaces

A class can inherit a parent class and implement multiple interfaces at the same time. Classes can only inherit from a single interface, and interfaces can be implemented and inherited from multiple interfaces.

class Class name implements Interface name 1,Interface name 2,Interface name 3... {
    // Constants (member variables) and methods (including abstract methods and default methods) in the interface can be obtained
    // Rewrite the abstract method in the interface [required]
    // Override the default method in the interface [optional if there is no duplicate name]
}		

class Class name extends Parent class implements Interface name 1,Interface name 2,Interface name 3... {
    // Rewrite the abstract method in the interface [required]
    // Override the default method in the interface [optional if there is no duplicate name]
}		

⚠️ be careful:

  1. If the default method has duplicate names, it must be overridden once
  2. When a class inherits a parent class and implements several interfaces, the member method in the parent class has the same name as the default method in the interface, and the subclass selects the member method of the parent class nearby!! ⚠️
  3. One interface can inherit another or more interfaces, which is similar to the inheritance between classes. Interface inheritance uses the extends keyword, and the child interface inherits the methods of the parent interface. If the default method in the parent interface has a duplicate name, the child interface needs to be rewritten once.
  4. When the sub interface overrides the default method, the default keyword can be retained.
  5. When subclasses override the default method, the default keyword cannot be reserved.

5, Inner class

Q: what is an internal class?
A: in Java, a class can be defined in another class. Such a class is called an inner class (nested class).

Q: when to use inner classes?
A: when describing things, if a thing contains other things that may be included, for example, when describing a car, the car also contains an engine, then the engine can be described using an internal class.

Q: what are the classifications of internal classes?
Answer: internal classes are divided into member internal classes, local internal classes and anonymous internal classes.

Q: what are the Compilation Characteristics of internal classes?
A: for an external class named OuterClass and an internal class named InnerClass, two class files will appear after successful compilation: OuterClass Class and OuterClass $InnerClass class.

Q: what are the access characteristics of internal classes?
A: the internal class can directly access the members in the external class. To access the internal class, the internal class object must be established.

5.1 anonymous inner class (key)


Create anonymous inner class through interface [case]

be careful:
   when creating an anonymous inner class through the implementation interface, the anonymous inner class cannot explicitly define a constructor, so the anonymous inner class only has an implicit parameterless constructor, so the parameter value cannot be passed in the parentheses after the new interface.

Create anonymous inner class by implementing class [case]

abstract class Device{
    private String name;
    public abstract double getPrice();
    public Device(){}
    public Device(String name){this.name = name;}
    //set and get methods of name
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
}

public class AnnoymousInner {
    public void test(Device d){
        System.out.println("Bought one"+d.getName()+",It's gone"+d.getPrice());
    }
    public static void main(String[] args){
        AnnoymousInner ai = new AnnoymousInner();
        //Call the constructor with parameters to create the object of Device anonymous implementation class
        ai.test(new Device("Electronic oscilloscope") {
            @Override
            public double getPrice() {
                return 10;
            }
        });
        //Call the parameterless constructor to create the object of the Device anonymous implementation class
        Device d = new Device() {
            //Initialization block
            {
                System.out.println("Initialization block of anonymous inner class···");
            }
            //Implement abstract methods
            @Override
            public double getPrice() {
                return 20;
            }
            //Override the instance method of the parent class
            public String getName(){
                return "keyboard";
            }
        };
        ai.test(d);
    }
}

be careful:

5.2 non static internal class

5.3 static internal class


[case]

public class InClassTest01 {
    private static int si = 10;
    private int a = 1;
    final int b = 2;
    int c = 3;
    
    /**
     * 1.Internal classes can directly access members of external classes, including private members
     * 2.To access the members of the internal class, the external class must establish the object of the internal class
     * */
    //Create a non static inner class
    class InClassTA{
        private int ia = 11;
        final int ib = 22;
        int ic = 33;
        public void ItestA(){
            System.out.println("Of non static inner classes Itest method.");
        }
        //1. A non static inner class cannot have static members
        //public static void sMethod(String[] args) {}
    }
    
    //Create static inner class
    static class InClassTB{
        //Static inner classes can contain static variables
        private static int ss = 100;
        private int sa = 44;
        final int sb = 55;
        int sc = 66;
        public void ItestB(){
            System.out.println("Of static inner classes ItestB method");
        }
        //Static methods of static inner classes
        public static void testC(){
            System.out.println("Static methods of static inner classes.");
            //1. Static internal classes cannot access instance variables of external classes, but can only access class variables of external classes
            System.out.println(si);
            //System.out.println(a);// Error a is a common member variable of an external class
        }
    }

    //Itest method of external class
    public void Itest(){
        System.out.println("External class Itest method.");
    }

    //External class main method
    public static void main(String[] args) {
        //An external class must create an object of the internal class to use members of the internal class
        //Create a non static inner class object:
        //Create internal object method 1:
//        InClassTest01 oct = new InClassTest01();
//        InClassTest01.InClassTA ict = oct.new InClassTA();
        //Method 2 for creating internal objects:
        InClassTest01.InClassTA ict = new InClassTest01().new InClassTA();
        //Internal object calls internal method
        ict.ItestA();
        //Non static inner class objects call private methods of non static inner classes
        System.out.println(ict.ia);

        //Create a static inner class object method:
        InClassTB ictb = new InClassTB();
        //1. Use the static internal class name as the caller to call internal class members (only members decorated with static can be called)
        System.out.println(InClassTB.ss);
        //Static methods of static inner classes
        InClassTB.testC();
        //2. Use the static inner class object as the caller to access the instance members (including private variables) of the static inner class
        System.out.println(ictb.sa);
    }
}

5.4 local internal class

   local internal class, which defines the local position in the external class method. Similar to the local variable in the access method, it can be accessed by calling the method.

// External class
class OuterClass {
	// Methods of external classes
	public void test() {
		// Local inner class (defined within the method of the outer class)
		class InnerClass {
			// Member variables of local inner classes
			public String name;
		    // Construction method of local inner class
			public InnerClass() {} // Nonparametric construction method
			public InnerClass(String name) { // Parametric construction method
				this.name = name;
			}
			// Member methods of local inner classes
			public void show() {
				System.out.println("In a local inner class show method");
			}
		}	
		// Instantiate local internal classes. Note that they can only be instantiated in the corresponding local scope!!!
		InnerClass in = new InnerClass("Xiao Ming");
		// Gets the member variable in the local inner class
		System.out.println("name:" + in.name);
		// Calling member methods in a local inner class
		in.show();
	}
}

Local internal class considerations

  1. Local inner classes can only be instantiated in the corresponding local scope.
  2. There cannot be any static variables or static methods in a local inner class.
  3. The local internal class is attached to the external class, so the internal class can be created only after the external class is created first.
  4. Accessing external class member variables: external classes this. Member variable, access external class member method: external class this. Member method.
  5. External local variables accessed by local internal classes must be decorated with final to prevent changing the value of external local variables. JDK1. There is no need to add final after 8.

5.5 internal use

6, Singleton class



7, Enumeration class

7.1 general

The enum type is jdk1 5 new features. When a class has only a limited number of objects and is certain, we call it an enumeration class.

For example:

  • Monday, Sunday
  • Gender: man (male), woman (female)
  • Season: Spring Festival... Winter
  • Payment methods: Cash (cash), WeChatPay (WeChat), Alipay (Alipay), BankCard (bank card), CreditCard (credit card).
  • Order status: unpaid, Paid, Delivered
    Return, Checked and Fulfilled

Enumeration classes are strongly recommended when you need to define a set of constants.

7.2 simple use of enumeration

Although the syntax structure of enum is different from that of class, it generates a class file after being compiled by the compiler, so enumeration is essentially a class, and the enumeration type is implicitly inherited from Java lang.Enum. Each member in an enumeration is actually an instance of an enumeration type.

[format]

enum Enumeration name {
    Enumerator body (constant list) //The enumeration body is to place some constants, and multiple constants are separated by commas
}

[example] call the instance format in enumeration class: enumeration class Instance name

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER; 
}

7.3 properties and methods of enumeration classes

characteristic:

  • Custom enumeration classes can add private constructors, properties and methods.
  • The constructor of an enumeration class can only use the private permission modifier.
  • All instances of an enumeration class must be explicitly listed in the enumeration class (, delimited; end). The listed instances will be automatically decorated with public static final, that is, they are constants.
  • Starting from JDK 1.5, you can use the object of the enumeration class as the expression in the switch structure, and the name of the enumeration value can be directly used in the case clause without adding the enumeration class as a qualification in front.

be careful:

  • The enumeration class object must be declared on the first line of the enumeration class.
  • When there are only constructors with parameters in the enumeration class, the enumeration class object needs to pass arguments.
  • The attributes in the enumeration class should be decorated with final and cannot be changed any more.

[example]

enum Season {
    //Enumeration objects must be declared on the first line of the class, separated by commas (as defined by the constructor format)
    SPRING("spring", "in the warm spring , flowers are coming out with a rush"), SUMMER("summer", "Summer heat"), AUTUMN("autumn", "fresh autumn weather"), WINTER("winter", "a world of ice and snow");

    private final String seasonName;
    private final String seasonDesc;

    //Enumerating methods can only be private
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

}

7.4 main methods of enum class

Main methods:

  • values(): returns an array of objects of enumeration type. This method can easily traverse all enumerated values.
  • valueOf(String str): you can convert a string into a corresponding enumeration class object. The string is required to be the "name" of the enumeration class object. If not, there will be a runtime exception: IllegalArgumentException.
  • toString(): returns the name of the object constant of the current enumeration class.
  • ordinal(): returns the order of the current enumeration constants (starting from 0).

8, Lambda

The essence of Lambda: it is the concrete object of the interface implementation class.

   Lambda is an anonymous function. We can understand the Lambda expression as a piece of code that can be passed (pass the code like data). Using it, you can write more concise and flexible code. As a more compact code style, the language expression ability of Java has been improved.

8.1 Lambda expression syntax (emphasis)

   Lambda expression: a new syntax element and operator introduced in Java 8 language. This operator is called "- >", which is called Lambda operator or arrow operator. It divides Lambda into two parts:

Left: Specifies the parameter list required by Lambda expression.
Right: Specifies the Lambda body, which is the implementation logic of the abstract method, that is, the function to be performed by the Lambda expression.

8.2 anonymous inner class to Lambda

public class LambdaTest01 {
    public static void main(String[] args) {
        //1. Lambda expression: it is converted from the internal class
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("Runnable Yes...1");
            }
        };
        
        //2. Convert to Lambda expression
        //The parentheses after the method name are used as the left part of the - > function
        //The content on the right of the arrow symbol is the method body of the abstract method (the specific implementation logic of the method)
        Runnable r2 = ()->{
            System.out.println("Runnable Yes...2");
        };
        r2.run();
        
        //3. The abstract method has two parameters and contains multiple execution statements (return values are allowed)
        Comparator<Integer> com = (x, y)->{
            System.out.println("Implement functional interface method!");
            return Integer.compare(x,y);
        };
        com.compare(11,22);
        
        //4. There is only one statement (condition) in the method body
        Runnable r4 = ()-> System.out.println("Runnbale Yes...4");
        r4.run();

        //The abstract method has one parameter, no return value, and only one statement in the method body
        //The type of str can be inferred from the generic t after consumer < T > and the writing of the type can be omitted
        Consumer<String> c1 = (str)-> System.out.println(str);
        c1.accept("hello");
    }
}

8.3 type inference

The type of Lambda expression depends on the context and is inferred by the compiler. This is called "type inference".

9, Functional interface

9.1 what is a functional interface

An interface that contains only one abstract method is called a functional interface.

You can create the object of this interface through Lambda expression. (if the Lambda expression throws a checked exception (i.e. non runtime exception), the exception needs to be declared on the abstract method of the target interface).

We can use the @ functional interface annotation on an interface to check whether it is a functional interface. At the same time, javadoc will also contain a declaration that this interface is a functional interface.

In Java util. The function package defines the rich functional interfaces of java8.

9.2 how to understand functional interfaces

  Java has been advocating "everything is object" since its birth. In Java, object-oriented (OOP) programming is everything. However, with the rise of python, scala and other languages and the challenges of new technologies, Java has to make adjustments to support a wider range of technical requirements, that is, Java can support not only OOP but also OOF (function oriented programming).

  in functional programming languages, the type of lambda expression is function. However, it is different in Java 8. Lambda expressions in Java 8 are objects, not functions. They must be attached to a special object type - functional interface.

   simply put, in Java 8, Lambda expression is an example of functional interface. This is the relationship between Lambda expressions and functional interfaces. That is, as long as an object is an instance of a functional interface, the object can be represented by a Lambda expression.

Therefore, those previously represented by anonymous inner classes can now be written in Lambda expressions.

9.3 Java has four built-in functional interfaces

9.4 user defined functional interface

Mark a functional interface with @ FunctionalInterface on the interface

@FunctionalInterface
interface MyFunc<T>{
	T getValue(T t);
}

Functional interfaces can be passed as parameters of methods, for example:

public String toUpperString(MyFunc<String> func,String str){
    //func in method is equivalent to an instance of MyFunc functional interface
    return func.getValue(str);
}

When calling the method, pass a Lambda expression to MyFunc (test represents the object of the current class)

String newStr = test.toUpperString((str) -> str.toUpperCase(), "abcdef");
System.out.println(newStr);//ABCDE

10, Stream API

10.1 introduction

   Stream is a key abstract concept for processing collections in Java 8. It can specify the operations you want to perform on collections, and can perform very complex operations such as finding, filtering and mapping data. Using the Stream API to operate on the collection data is similar to the database query executed with SQL. In short, the Stream API provides an efficient and easy-to-use way to process data.

   the difference between Stream and Collection: Collection is a static memory data structure, while Stream is related to calculation. The former is mainly memory oriented and stored in memory, while the latter is mainly CPU oriented and realizes calculation through CPU.

   before Java 8, the operation of the set needs to write out the processing process. For example, to filter the data that meets the conditions in the set, you need to traverse each element in the set one by one, then judge whether each element meets the conditions one by one, and finally save and return the elements that meet the conditions. Stream provides a more convenient operation for collection filtering. It only needs to pass in the filtering conditions that implement the function interface as parameters. Stream will operate by itself and return the appropriate elements in the same way as stream, and finally receive them.

   Stream is a data channel used to manipulate the sequence of elements generated by data sources (sets, arrays, etc.). "Set is about data, Stream is about calculation!"

The characteristics of Stream are as follows:

  • ① Stream is not a collection and does not store elements by itself.
  • ② Stream does not change the source object. Instead, they return a new stream that holds the result.
  • ③ Stream operations are deferred. This means that they wait until the results are needed.

10.2 three steps of stream operation

10.3 creating a Stream

10.3.1 mode 1: through collection

The Collection interface in Java 8 is extended to provide two methods to obtain streams:

  • Default stream < E > stream(): returns a sequential stream
  • Default stream < E > parallelstream(): returns a parallel stream
/**
 * junit4(Unit test framework)
 */
public class StreamTest01 {
    
    //Test create Stream
    @Test
    public void testCreateStream1(){
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        
        System.out.println("Often create an ordered sequential flow**************************");
        //Call the stream() method to create a sequential stream (the output order is the same as the insertion order)
        Stream<Integer> stream = list.stream();
        stream.forEach((Integer i)-> System.out.println(i));
        
        //Create a parallel stream (unordered) (understand!!!)
        System.out.println("Create an unordered parallel stream**************************");
        Stream<Integer> parallelStream = list.parallelStream();
        parallelStream.forEach((Integer i)-> System.out.println(i));
    }
    
}

10.3.2 mode 2: through array

The static method stream() of Arrays in Java 8 can obtain the array stream: overloaded form, which can handle Arrays of corresponding basic types:

  • Static < T > stream < T > stream (t [] array): returns a stream
//Test create Stream --- through array
@Test
public void createArrayStream(){
	int[] is = {1,2,3};
    IntStream stream = Arrays.stream(is);
    stream.forEach((i)-> System.out.println(i));
}

10.3.3 mode 3: through stream of()

You can call the static method of() of the Stream class to create a Stream by displaying the value. It can receive any number of parameters.

  • Public static < T > stream < T > of (t... Values): returns a stream
//Create a Stream through the static method of () of the Stream class
@Test
public void createStreamOf(){
	Stream<Integer> stream = Stream.of(1,2,3,4);
    stream.forEach((i)-> System.out.println(i));
}

10.4 Stream intermediate operation

   multiple intermediate operations can be connected to form a pipeline. Unless the termination operation is triggered on the pipeline, the intermediate operation will not perform any processing! When the operation is terminated, it is processed all at once, which is called "inert evaluation".

10.4.1 screening and slicing


Requirement 1: create an Employee class Employee, create an Employee collection, and find out the information of employees with salary > 6500

	//Requirement 1: create an Employee class Employee, create an Employee collection, and find out the information of employees with salary > 6500
    @Test
    public void test01(){
        //Get employee collection
        List<Employee> all = EmployeeManage.getAll();
        //Create stream
        Stream<Employee> stream = all.stream();
        //The parameter of filter() is predict < T >
        stream.filter( (e)->{return e.getSalary()>6500;} ).forEach((e)->{
            System.out.println(e);
        });
    }


Requirement 2: remove duplicate employee information

	//Requirement 2: remove duplicate employee information
    @Test
    public void test02(){
        //Get employee collection
        List<Employee> all = EmployeeManage.getAll();
        //Create stream
        Stream<Employee> stream = all.stream();
        //The parameter of filter() is predict < T >
        //distinct() removes duplicate elements through the hashCode() and equals() methods of the elements generated by the stream
        stream.filter( (e)->{return e.getSalary()>6500;} ).distinct().forEach((e)->{
            System.out.println(e);
        });
    }


Requirement: output the information of the next two employees (i.e. skip the first four elements)

//Requirement: output the information of the next two employees (i.e. skip the first four elements)
    @Test
    public void test03(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream();
        stream.distinct().skip(4).forEach((employee -> System.out.println(employee)));
    }

10.4.2 mapping


Requirement 1: convert a group of lowercase words to uppercase

//Converts a group of lowercase letters to uppercase letters
    @Test
    public void test01(){
        //Create a stream
        Stream<String> stream = Stream.of("hello", "wuhan", "zhangzhou");
        stream.map( (str)->str.toUpperCase() ).forEach((str)-> System.out.println(str));
    }

Demand 2: obtain the salary of all employees whose salary is greater than 7000

//Obtain the salary of all employees whose salary is greater than 7000
    @Test
    public void test02(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream();
        stream.filter( emp -> emp.getSalary()>7000).map( emp-> emp.getSalary()).forEach(salary-> System.out.println(salary));
    }

10.4.3 sorting


Requirement 1: sort a set of integers 10, 21, - 7, 3, 19 and 14 naturally

	//Requirement 1: sort a set of integers 10, 21, - 7, 3, 19 and 14 naturally
    @Test
    public void test(){
        Stream<Integer> stream = Stream.of(10, 21, -7, 3, 19, 14);
        //Natural sorting
        Stream<Integer> sorted = stream.sorted();
        sorted.forEach( e-> System.out.print(e+",") );
    }


Demand 2: it is arranged in ascending order by employee's salary and displays all employee information

	//Demand 2: it is arranged in ascending order by employee's salary and displays all employee information
    @Test
    public void test1(){
        List<Employee> all = EmployeeManage.getAll();
        
        System.out.println("++++++++++++Wage ascending order++++++++++++");
        Stream<Employee> stream = all.stream().distinct();
        Stream<Employee> stream2 = stream.sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        stream2.forEach( e -> System.out.println(e));
        
        System.out.println("++++++++++++Wage descending order++++++++++++");
        Stream<Employee> streamm = all.stream().distinct();
        Stream<Employee> stream3 = streamm.sorted((e1, e2) -> Double.compare(e2.getSalary(),e1.getSalary()));
        stream3.forEach( e -> System.out.println(e));
    }


Demand 3: sort by employee's salary in ascending order, display all employee information, and sort by age if the salary is the same

	//Demand 3: sort by employee's salary in ascending order, display all employee information, and sort by age if the salary is the same
    @Test
    public void test2(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        Stream<Employee> sortedStream = stream.sorted((e1, e2) -> {
            //If the salary is the same, it is arranged in ascending order of age
            if (e1.getSalary() == e2.getSalary()) {
                return Integer.compare(e1.getAge(), e2.getAge());
            }
            //Otherwise, the salary will be arranged in ascending order
            return Double.compare(e1.getSalary(), e2.getSalary());
            //The above code can be simplified to
            //return e1.getSalary()==e2.getSalary() ? Integer.compare(e1.getAge(),e2.getAge()) : Double.compare(e1.getSalary(),e2.getSalary());
        });
        sortedStream.forEach( e-> System.out.println(e) );
    }

10.5 Stream termination

The terminal operation generates results from the pipeline of the stream. The result can be any value that is not a stream, such as List, Integer, or even void.

After the stream is terminated, it cannot be used again.

   multiple intermediate operations can be connected to form a pipeline. Unless the termination operation is triggered on the pipeline, the intermediate operation will not perform any processing!

10.5.1 matching and searching


Demand 1: check whether the salary of all employees is greater than or equal to 5500

//Demand 1: check whether the salary of all employees is greater than or equal to 5500
    @Test
    public void test3(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        System.out.println("Whether the wages of employees are greater than 5500:"+stream.allMatch(e -> e.getSalary() >= 5500));
    }


Demand 2: is there an employee whose salary is greater than 10000

	//Demand 2: is there an employee whose salary is greater than 10000
    @Test
    public void test4(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        System.out.println("Whether there are employees with salary greater than 10000:"+stream.anyMatch( e->e.getSalary() > 10000 ));
    }


Demand 3: find out the number of employees whose salary is greater than 6500

	//Demand 3: find out the number of employees whose salary is greater than 6500
    @Test
    public void test5(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct().filter(e->e.getSalary()>6500);
        System.out.println("Number of employees with salary greater than 6500:"+stream.count());
    }

Demand 4: find out the maximum salary of employees

	//Demand 4: find out the maximum salary of employees
    @Test
    public void test6(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        
        //The salary you want to return is in the package status Employee, so you return the Optional class
        Optional<Employee> maxOpt = stream.max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        Employee employee = maxOpt.get();
        System.out.println(employee.getName()+",The maximum salary of the employee is:"+employee.getSalary());
    }


Requirement 5: employees who return the minimum wage

    //Demand 5: find out the minimum wage of employees
    @Test
    public void test7(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        
        //The salary you want to return is in the package status Employee, so you return the Optional class
        Optional<Employee> minOpt = stream.min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        Employee employee = minOpt.get();
        System.out.println(employee.getName()+",The minimum wage of the employee is:"+employee.getSalary());
    }


Demand 6: return all employees whose salary is greater than 6000

//Demand 6: return all employees whose salary is greater than 6000
    @Test
    public void test8(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct().filter(e->e.getSalary()>6000);
        stream.forEach(e-> System.out.println(e));
    }


Extension: when a method parameter is a Lambda expression (an instance of a functional interface) and there is only one execution statement, it can be abbreviated to the form of class name:: method name.

10.5.2 reduction


Requirement 1: calculate the sum of figures 1-10

//Demand 1: calculate the sum of figures 1-10 [method 1]
    @Test
    public void test10(){
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //0 is the initial value returned by the following lambda expression
        Integer isum = stream.reduce(0,(a,b)->Integer.sum(a,b));
        System.out.println(isum);
    }	
    
//Demand 1: calculate the sum of figures 1-10 [method 2]
    @Test
    public void test9(){
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Optional<Integer> opt = stream.reduce((a, b) -> Integer.sum(a,b));
        
        //More streamlined writing
        //stream.reduce(Integer::sum);
        Integer isum = opt.get();
        System.out.println(isum);
    }


Demand 2: calculate the sum of wages of all employees

//Demand 2: calculate the sum of wages of all employees
    @Test
    public void test11(){
        List<Employee> all = EmployeeManage.getAll();
        Stream<Employee> stream = all.stream().distinct();
        //stream.reduce( (e1,e2)->Double.sum(e1.getSalary(),e2.getSalary()) );
        Stream<Double> doubleStream = stream.map(e -> e.getSalary());
        Double sumSalary = doubleStream.reduce(0.0,(e1, e2) -> Double.sum(e1, e2));
        System.out.println("Total wages:"+sumSalary);
    }

10.5.3 collection (preferred recommendation)

The implementation of methods in the Collector interface determines how to perform collection operations (such as collecting List, Set and Map).

In addition, the Collectors utility class provides many static methods to easily create common collector instances. The specific methods and examples are shown in the following table:

Demand 1: find the total salary of all employees

	//Calculate the sum of employees' wages
    @Test
    public void test3(){
        Stream<Employee> stream = EmployeeManage.getAll().stream().distinct();
        
        //E - > E. short for getsalary(): Employee::getSalary
        Double collect = stream.collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("Total wages of all employees:"+collect);
    }


Demand 2: find the average salary of all employees

//Demand 2: find the average salary of all employees
    @Test
    public void test4(){
        Stream<Employee> stream = EmployeeManage.getAll().stream().distinct();
        Double aDouble = stream.collect(Collectors.averagingDouble(e -> (int) e.getSalary()));
        System.out.println("Average salary of all employees:"+aDouble);
    }


Demand 3: information about the lowest paid employees

//Minimum wage employee information
    @Test
    public void test5(){
        Stream<Employee> stream = EmployeeManage.getAll().stream().distinct();
        Optional<Employee> opt = stream.collect(Collectors.minBy(Comparator.comparingDouble(e -> e.getSalary())));
        Employee employee = opt.get();
        System.out.println("The minimum wage of the employee:"+employee.getName()+","+employee.getSalary());
    }

Topics: Java Back-end