Java se -- phase 2 4

generic paradigm

1. Benefits of generics

  • At compile time, check the type of added elements to improve security
  • When the ClassCastException of the runtime is transferred to the compilation time, it becomes a compilation failure.
  • It reduces the number of type conversions and improves efficiency

2. Precautions

  • 1. Interface list, public class HashSet {}..., T,E can only be reference types
  • 2. After specifying a specific type for a generic type, you can pass in the type or its subclass type

3. Custom generics

1. Basic grammar

class Class name<T,R...>{
    member
}

interface IYse<T,R...>{}

2. Pay attention to details

  • Common members can use generics (properties, methods)
  • Arrays that use generics cannot be initialized
  • Generics of classes cannot be used in static methods
  • The type of a generic class is determined when the object is created (because the type needs to be determined when the object is created)
  • If no generic type is specified when creating an Object again, the default is Object
public class CustomGeneric_ {
    public static void main(String[] args) {

        //T=Double, R=String, M=Integer
        Tiger<Double,String,Integer> g = new Tiger<>("john");
        g.setT(10.9); //OK
        //g.setT("yy"); // Error, wrong type
        System.out.println(g);
        Tiger g2 = new Tiger("john~~");//OK T=Object R=Object M=Object
        g2.setT("yy"); //OK, because T=Object "yy"=String is a subclass of Object
        System.out.println("g2=" + g2);

    }
}

//Lao Han's interpretation
//1. Tiger is generic, so we call tiger a custom generic class
//2. The identifier of T, R, m generic type is generally a single uppercase letter
//3. There can be multiple generic identifiers
//4. Ordinary members can use generics (properties, methods)
//5. Generic arrays cannot be initialized
//6. Class generics cannot be used in static methods
class Tiger<T, R, M> {
    String name;
    R r; //Property to generic
    M m;
    T t;
    //Because the array cannot determine the type of T in new, it cannot open space in memory
    T[] ts;

    public Tiger(String name) {
        this.name = name;
    }

    public Tiger(R r, M m, T t) {//Constructors use generics

        this.r = r;
        this.m = m;
        this.t = t;
    }

    public Tiger(String name, R r, M m, T t) {//Constructors use generics
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }

    //Because static is class related, the object has not been created when the class is loaded
    //Therefore, if static methods and static properties use generics, the JVM cannot complete initialization
//    static R r2;
//    public static void m1(M m) {
//
//    }

    //Methods use generics

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public R getR() {
        return r;
    }

    public void setR(R r) {//Method to generic
        this.r = r;
    }

    public M getM() {//Return types can use generics
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        return "Tiger{" +
                "name='" + name + '\'' +
                ", r=" + r +
                ", m=" + m +
                ", t=" + t +
                ", ts=" + Arrays.toString(ts) +
                '}';
    }
}

4. Generic inheritance and wildcards

  • Generics are not inherited

  • <?>: Any generic type is supported
  • <? Extensions a >: supports class A and subclasses of class A, and specifies the upper limit of generics
  • <? Super a >: supports class A and class a parent classes, not limited to direct parent classes, and specifies the lower limit of generics
public class GenericExtends {
    public static void main(String[] args) {

        Object o = new String("xx");

        //Generics have no inheritance
        //List<Object> list = new ArrayList<String>();

        //Examples are given to illustrate the use of the following three methods
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();

        //If list <? > c. Any generic type can be accepted
        printCollection1(list1);
        printCollection1(list2);
        printCollection1(list3);
        printCollection1(list4);
        printCollection1(list5);

        //List<?  Extensions AA > C: indicates the upper limit. AA or AA subclasses are acceptable
//        printCollection2(list1);//×
//        printCollection2(list2);//×
        printCollection2(list3);//√
        printCollection2(list4);//√
        printCollection2(list5);//√

        //List<?  Super AA > C: support AA class and its parent class, not limited to direct parent class
        printCollection3(list1);//√
        //printCollection3(list2);//×
        printCollection3(list3);//√
        //printCollection3(list4);//×
        //printCollection3(list5);//×
    }
    
    // ?  extends AA indicates the upper limit. AA or AA subclasses can be accepted
    public static void printCollection2(List<? extends AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }
    }

    //Description: List <? > Indicates that any generic type is acceptable
    public static void printCollection1(List<?> c) {
        for (Object object : c) { // Wildcard. When taken out, it is Object
            System.out.println(object);
        }
    }

    // ?  super subclass class name AA: supports AA class and the parent class of AA class, not limited to the direct parent class,
    //Specifies the lower bound for generics
    public static void printCollection3(List<? super AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }
    }

}

class AA {}
class BB extends AA {}
class CC extends BB {}

thread

  • Program: a set of instructions written in a language to complete a specific task. In short, it is code

  • Concurrency: multiple tasks are executed alternately at the same time

  • Parallel: multiple tasks are executed simultaneously at the same time

1. Basic introduction

  • In Java, at least 2 threads are started each time the program runs. One is the main thread and the other is the garbage collection thread. Because every time a class is executed using java commands, a JVM is actually started, and each JVM actually starts a process in the operating system.

  • There are two ways to create threads

    • Inherit the Thread class and override the run method
    • Implement the Runnable interface and rewrite the run method
public class Thread01 {
    public static void main(String[] args) throws InterruptedException {

        //Create a Cat object that can be used as a thread
        Cat cat = new Cat();
        /*
            (1)
            public synchronized void start() {
                start0();
            }
            (2)
            //start0() It is a local method, a JVM call, and the bottom layer is a c/c + + implementation
            //The real effect of multithreading is start0(), not run
            private native void start0();
         */
        cat.start();//Start the thread - > the run method of cat will eventually be executed
        System.out.println("The main thread continues execution" + Thread.currentThread().getName());//Name main
        for(int i = 0; i < 60; i++) {
            System.out.println("Main thread i=" + i);
            //Hibernate the main thread
            Thread.sleep(1000);
        }

    }
}
class Cat extends Thread {

    int times = 0;
    @Override
    public void run() {//Rewrite the run method and write your own business logic

        while (true) {
            //The thread every 1 second. Output "meow, meow, I'm a kitten" on the console
            System.out.println("Meow meow, I'm a kitten" + (++times) + " Thread name=" + Thread.currentThread().getName());
            //Let the thread sleep for 1 second ctrl+alt+t
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(times == 80) {
                break;//When the times reaches 80, exit while, and the thread will exit
            }
        }
    }
}

2. Common methods

1,start():Start the of the current thread and call the of the current thread run()method
2,currentThread():Static method that returns the thread executing the current code
1,yield():The comity of threads. Give up CPU,Let other threads execute first, but the comity event is uncertain, and all may not be comity successful
2,join():Thread queue jumping. Once the queued thread is checked successfully, it must first complete all the tasks of the inserted thread

User thread and daemon thread

  • User thread: also called worker thread, when the task of the thread is completed or the notification method ends
  • Daemon thread: it generally serves the worker thread. When all user threads end, the daemon thread ends automatically
  • Common daemon threads: garbage collection mechanism
If we want to be main When the thread ends, the child thread ends automatically,Just set the child thread as the daemon thread
setDaemon(true); //Set as daemon thread

3. Thread life cycle

  • NEW Threads that have not been started are in this state.
  • RUNNABLE The thread executing in the Java virtual machine is in this state. It can be refined into the following two states
    • Ready: ready status
    • Running: running status
  • BLOCKED Threads that are blocked waiting for a monitor lock are in this state.
  • WAITING A thread that is waiting for another thread to perform a specific action is in this state.
  • TIMED_WAITING The thread that is waiting for another thread to perform the action for the specified waiting time is in this state.
  • TERMINATED The exited thread is in this state

Thread priority setting

1. Thread scheduling

  • Time slice

  • Preemptive: high priority threads preempt CPU

2. Java scheduling

  • Threads with the same priority form a first in first out queue (first in first out service) and use the time slice strategy
  • For high priority, the preemptive strategy of priority scheduling is used

3. Thread priority

  • Thread priority level
    • MAX_PRIORITY: 10
    • MIN_PRIORITY: 1
    • NORM_PRIORITY: 5
  • Design method
    • getPriority(): returns the thread priority value
    • setPriority(int newPriority): change the priority of the thread
  • explain
    • When a thread is created, it inherits the priority of the parent thread
    • Low priority is only a low probability of scheduling, not necessarily called after high priority threads

4. Thread synchronization mechanism

  • 1. In multi-threaded programming, some sensitive data are not allowed to be accessed by multiple threads at the same time. At this time, synchronous access technology is used to ensure that at most one thread can access the data at any one time to ensure the integrity of the data.
  • 2. It can also be understood here: thread synchronization means that when one thread is operating on memory, other threads cannot operate on the memory address until the thread completes the operation

5,Synchronized

  • Why thread safety issues arise

    • Shared data
  • explain:

    • 1. The code that operates shared data is the code that needs to be synchronized
    • 2. Shared data: variables operated by multiple threads. For example, a ticket is sharing data.
    • 3. Synchronous monitor, commonly known as lock. The object of any class can act as a lock.
      • Requirement: multiple threads must share the same lock.

Synchronization mode

  • Benefits: solves the thread safety problem
  • Disadvantages: when operating synchronous code blocks, only one thread can participate, and other threads wait. It is equivalent to a single thread, which is inefficient

6. Mutex

1. Basic introduction

  • 1. In Java language, the concept of object mutex is introduced to ensure the integrity of shared data operation
  • 2. Each object corresponds to a tag called "mutex", which is used to ensure that only one thread can access the object at any time.
  • 3. The keyword synchronized to associate with the mutex of the object. When an object is decorated with synchronized, it indicates that the object can only be accessed by one thread at any time
  • 4. Limitation of synchronization: the execution efficiency of the program should be reduced
  • 5. The lock of the synchronization method (non static) can be this or other objects (the same object is required). The default lock object is this
  • 6. The lock of the synchronous method (static) is the current class itself. The default lock object is the current class class

7. Thread deadlock

1. Basic introduction

  • Different threads occupy the synchronization resources needed by the other party and do not give up. They are waiting for the other party to give up the synchronization resources they need, forming a thread deadlock
  • After deadlock occurs, there will be no exception or prompt, but all threads are blocked and cannot continue|

2. Solution

  • Special algorithms, principles
  • Minimize the definition of synchronization resources
  • Try to avoid nested synchronization

I/O flow

1. Documents

1. Basic introduction

  • File: where data is stored

  • File stream: files are operated in the form of stream in the program

2. Common methods

  • 1,new File(String pathname)

  • 2. new File(File parent,String child) / / build according to the parent directory file + child path

  • 3. new File(String parent,String child) / / build according to parent directory + child path

2. Classification of flow

  • Different operation data units: byte stream and character stream
  • The data flow direction is different: input flow and output flow
  • According to the different roles of the flow: node flow, processing flow / wrapper flow

3. Byte stream

1,FileInputStream

public class FileInputStream_ {
    public static void main(String[] args) {
    }
    /**
     * Show me reading files
     * The efficiency of reading a single byte is relatively low
     * -> Use read(byte[] b)
     */
    @Test
    public void readFile01() {
        String filePath = "e:\\hello.txt";
        int readData = 0;
        FileInputStream fileInputStream = null;
        try {
            //Create a FileInputStream object to read files
            fileInputStream = new FileInputStream(filePath);
            //Read one byte of data from the input stream. If no input is available, this method blocks.
            //If - 1 is returned, the reading is completed
            while ((readData = fileInputStream.read()) != -1) {
                System.out.print((char)readData);//Convert to char display
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //Close the file stream and free up resources
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * Use read(byte[] b) to read files to improve efficiency
     */
    @Test
    public void readFile02() {
        String filePath = "e:\\hello.txt";
        //Byte array
        byte[] buf = new byte[8]; //Read 8 bytes at a time
        int readLen = 0;
        FileInputStream fileInputStream = null;
        try {
            //Create a FileInputStream object to read files
            fileInputStream = new FileInputStream(filePath);
            //Read up to b.length bytes of data from the input stream into the byte array. This method blocks until some input is available.
            //If - 1 is returned, the reading is completed
            //If the reading is normal, the number of bytes actually read is returned
            while ((readLen = fileInputStream.read(buf)) != -1) {
                System.out.print(new String(buf, 0, readLen));//display
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //Close the file stream and free up resources
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2,FileOutputStream

@Test
public void writeFile() {
    //Create FileOutputStream object
    String filePath = "e:\\a.txt";
    FileOutputStream fileOutputStream = null;
    try {
        //Get FileOutputStream object
        //Teacher description
        //1. Create new fileoutputstream (filepath). When the content is written, the original content will be overwritten
        //2. new FileOutputStream(filePath, true) creation method. When the written content is, it is appended to the back of the file
        fileOutputStream = new FileOutputStream(filePath, true);
        //Write a byte
        //fileOutputStream.write('H');//
        //Write string
        String str = "hsp,world!";
        //str.getBytes() can convert string - > byte array
        //fileOutputStream.write(str.getBytes());
        /*
            write(byte[] b, int off, int len) Writes len bytes to this file output stream from the specified byte array at offset off
             */
        fileOutputStream.write(str.getBytes(), 0, 3);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class FileCopy {
    public static void main(String[] args) {
        //When the file copy is complete, e: \ \ koala Jpg copy c:\
        //Train of thought analysis
        //1. Create the input stream of the file and read the file into the program
        //2. Create the output stream of the file and write the read file data to the specified file
        String srcFilePath = "e:\\Koala.jpg";
        String destFilePath = "e:\\Koala3.jpg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileInputStream = new FileInputStream(srcFilePath);
            fileOutputStream = new FileOutputStream(destFilePath);
            //Define a byte array to improve the reading effect
            byte[] buf = new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf)) != -1) {
                //After reading, it is written to the file through fileOutputStream
                //That is, reading and writing
                fileOutputStream.write(buf, 0, readLen);//Be sure to use this method
            }
            System.out.println("Copy ok~");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //Close the input and output streams to free up resources
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4. Character stream

1,FileReader

1. Common methods

  • 1,new FileReader(File/String)
  • 2. Read: each time a single character is read, the character is returned. If it reaches the end of the file, it returns - 1
  • 3. read(char []): read multiple characters into the array in batch, and return the number of characters read. If it reaches the end of the file, return - 1
  • 4. new String(char [): convert char [to String
  • 5. new String(char,off.len): converts the specified part of char [] into a String

2,FileWriter

1. Common methods

  • 1. new FileWriter(File/String): overwrite mode, which is equivalent to that the pointer of the stream is at the head end
  • 2. new FileWriter(File/String,true): append mode, which is equivalent to the flow pointer at the end
  • 3. write(int): writes a single character
  • 4. write(char []): writes the specified array
  • 5. write(char[l.off,len): writes the specified part of the specified array
  • 6. write (string): writes the entire string
  • 7. write(string,off,len): writes the specified part of the string
  • String class: toCharArray: convert string to charD
  • After the FileWriter is used, it must be closed or flushed, otherwise the specified file cannot be written!
import org.junit.Test;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriter_ {
    public static void main(String[] args) {

        String filePath = "e:\\note.txt";
        //Create FileWriter object
        FileWriter fileWriter = null;
        char[] chars = {'a', 'b', 'c'};
        try {
            fileWriter = new FileWriter(filePath);//The default is overwrite write
//            3) write(int): writes a single character
            fileWriter.write('H');
//            4) write(char []): writes the specified array
            fileWriter.write(chars);
//            5) write(char[],off,len): writes the specified part of the specified array
            fileWriter.write("Han Shunping Education".toCharArray(), 0, 3);
//            6) write (string): writes the entire string
            fileWriter.write(" Hello, Beijing~");
            fileWriter.write("After the wind and rain, you will see the rainbow");
//            7) write(string,off,len): writes the specified part of the string
            fileWriter.write("Shanghai Tianjin", 0, 2);
            //In case of large amount of data, circular operation can be used
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //Corresponding to FileWriter, you must close the stream or flush to write data to the file
            //Lao Han knows the reason from the source code
            /*
                Look at the code
                private void writeBytes() throws IOException {
        this.bb.flip();
        int var1 = this.bb.limit();
        int var2 = this.bb.position();

        assert var2 <= var1;

        int var3 = var2 <= var1 ? var1 - var2 : 0;
        if (var3 > 0) {
            if (this.ch != null) {
                assert this.ch.write(this.bb) == var3 : var3;
            } else {
                this.out.write(this.bb.array(), this.bb.arrayOffset() + var2, var3);
            }
        }

        this.bb.clear();
    }
             */
            try {
                //fileWriter.flush();
                //Close the file stream, equivalent to flush() + close
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Program end...");
    }

    @Test
    public void test07() throws Exception{
        String src="F:\\aaaa.txt";
        char[] buffer = new char[1024];
        FileReader fileReader = new FileReader(src);
        int len = 0;
        while ((len = fileReader.read(buffer))!=-1){
            System.out.print(new String(buffer,0,len));
        }
        fileReader.close();
    }
}

5. Node flow and processing flow

1. Basic introduction

  • Node flows can read and write data from a specific data source
  • Processing flow (also known as wrapper flow) is "connected" on the existing flow (node flow or processing flow), providing more powerful read and write functions for programs

Differences and connections

  • Node flow is the underlying flow / low-level flow, which is directly connected to the data source.
  • Processing flow wrapping node flow can not only eliminate the implementation differences of different node flows, but also provide a more convenient method to complete input and output.
  • The processing flow (also known as wrapping flow) wraps the node flow, uses the decorator design pattern, and is not directly connected to the data source

Function embodiment

  • 1. Performance improvement: mainly increase the buffer to improve the efficiency of input and output.
  • 2. Convenient operation: the processing flow may provide a series of convenient methods to input and output a large number of data at one time
    It is more flexible and convenient to use

2. BufferedReader and BufferedWriter

@Test
public void test01() throws Exception {

    String filePath = "e:\\a.java";
    //Create bufferedReader
    BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
    //read
    String line; //Read by line, high efficiency
    //explain
    //1. bufferedReader.readLine() reads files by line
    //2. When null is returned, it indicates that the file has been read
    while ((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
    }
    //Close the flow. Note here that you only need to close the BufferedReader, because the bottom layer will automatically close the node flow
    //FileReader. 
    /*
            public void close() throws IOException {
                synchronized (lock) {
                    if (in == null)
                        return;
                    try {
                        in.close();//in The new FileReader(filePath) we passed in is closed
                    } finally {
                        in = null;
                        cb = null;
                    }
                }
            }
         */
    bufferedReader.close();
}
public static void main(String[] args) throws IOException {
    String filePath = "e:\\ok.txt";
    //Create BufferedWriter
    //explain:
    //1. new FileWriter(filePath, true) means to write by appending
    //2. new FileWriter(filePath), which means to write in the way of overwrite
    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
    bufferedWriter.write("hello, Han Shunping Education!");
    bufferedWriter.newLine();//Insert a system related line feed
    bufferedWriter.write("hello2, Han Shunping Education!");
    bufferedWriter.newLine();
    bufferedWriter.write("hello3, Han Shunping Education!");
    bufferedWriter.newLine();

    //Note: Just close the outer stream. The incoming new FileWriter(filePath) will be closed at the bottom
    bufferedWriter.close();
}
public static void main(String[] args) {
    //Lao Han description
    //1. BufferedReader and BufferedWriter are installation character operations
    //2. Do not operate binary files [sound, video, doc, pdf], which may cause file damage
    //BufferedInputStream
    //BufferedOutputStream
    String srcFilePath = "e:\\a.java";
    String destFilePath = "e:\\a2.java";
    //        String srcFilePath = "e:\0245 Han Shunping zero basic Java leads out this.avi";
    //        String destFilePath = "e:\a2 Han Shunping. avi";
    BufferedReader br = null;
    BufferedWriter bw = null;
    String line;
    try {
        br = new BufferedReader(new FileReader(srcFilePath));
        bw = new BufferedWriter(new FileWriter(destFilePath));
        //Note: readLine reads a line, but there is no line feed
        while ((line = br.readLine()) != null) {
            //Every time a row is read, it is written
            bw.write(line);
            //Insert a new line
            bw.newLine();
        }
        System.out.println("Copy complete...");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //Close flow
        try {
            if(br != null) {
                br.close();
            }
            if(bw != null) {
                bw.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. BufferedInputStream and BufferedOutputStream

public class copy {
    public static void main(String[] args) {
        String srcFile="F:\\aaa.mp4";
        String desFile="F:\\bbb.mp4";
        BufferedInputStream bis=null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFile));
            bos = new BufferedOutputStream(new FileOutputStream(desFile));
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = bis.read(bytes))!=-1){
                bos.write(bytes,0,len);
            }
            System.out.println("File copy complete");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis!=null){
                    bis.close();
                }
                if (bos!=null){
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4. ObjectInputStream and objectoutstream

1. Basic introduction

  • 1. Function: provides methods for serialization and deserialization of basic types or object types

  • 2. ObjectOutputStream provides serialization

  • 3. ObjectlnputStream provides deserialization

  • serialization and deserialization

    • 1. Serialization is to save the value and data type of data when saving data
    • 2. Deserialization is to recover the value and data type of data when recovering data
    • 3. If an object needs to support serialization mechanism, its class must be serializable. In order to make a class serializable, the class must implement one of the following two interfaces:
      • Serializable this is a tag interface without methods
      • Externalizable this interface has methods to implement, so we generally implement the above Serializable interface

2. Code display

serialize

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class OOS {
    public static void main(String[] args) throws Exception {
        //After serialization, the saved file format is not text, but saved according to its format
        String filePath = "e:\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        //Serialize data to e: \ data dat
        oos.writeInt(100);// Int - > integer (serializable implemented)
        oos.writeBoolean(true);// Boolean - > Boolean (serializable is implemented)
        oos.writeChar('a');// Char - > character (serializable is implemented)
        oos.writeDouble(9.5);// Double - > double (serializable is implemented)
        oos.writeUTF("Han Shunping Education");//String
        //Save a dog object
        oos.writeObject(new Dog("Wangcai", 10, "Japan", "white"));
        oos.close();
        System.out.println("Data saved(serialized form )");
    }
}
//If you need to serialize an object of a class, implement Serializable
public class Dog implements Serializable {
    private String name;
    private int age;
    //When serializing an object, all attributes in it are serialized by default, except for members decorated with static or transient
    private static String nation;
    private transient String color;
    //When serializing an object, it is required that the type of the attribute inside also implement the serialization interface
    private Master master = new Master();

    //serialVersionUID is the version number of serialization, which can improve compatibility
    private static final long serialVersionUID = 1L;

    public Dog(String name, int age, String nation, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
        this.nation = nation;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}' + nation + " " +master;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

class Master implements Serializable {
}

Deserialization

public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        //Specifies the file to deserialize
        String filePath = "e:\\data.dat";

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

        //read
        //Teacher interpretation
        //1. The order of reading (deserialization) needs to be consistent with the order in which you save data (serialization)
        //2. Otherwise, an exception will occur

        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());

        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());


        //The compilation type of Dog is object, and the running type of Dog is Dog
        Object dog = ois.readObject();
        System.out.println("Operation type=" + dog.getClass());
        System.out.println("dog information=" + dog);//Underlying object - > dog

        //Here are particularly important details:

        //1. If we want to call Dog's method, we need to transform down
        //2. We need to put the definition of Dog class in a place that can be referenced
        Dog dog2 = (Dog)dog;
        System.out.println(dog2.getName()); //Wangcai

        //Close the stream, just close the outer stream, and the bottom stream will close the FileInputStream stream stream
        ois.close();
    }
}
public class SerTest {
	public static void main(String[] args) throws Exception {
		// Create student object
		Student student = new Student("Lao Wang", "laow");
		Student student2 = new Student("Lao Zhang", "laoz");
		Student student3 = new Student("Lao Li", "laol");

		ArrayList<Student> arrayList = new ArrayList<>();
		arrayList.add(student);
		arrayList.add(student2);
		arrayList.add(student3);
		// Serialization operation
		// serializ(arrayList);
		
		// Deserialization  
		ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("list.txt"));
		// Read the object and force it to ArrayList type
		ArrayList<Student> list  = (ArrayList<Student>)ois.readObject();
		
      	for (int i = 0; i < list.size(); i++ ){
          	Student s = list.get(i);
        	System.out.println(s.getName()+"--"+ s.getPwd());
      	}
	}

	private static void serializ(ArrayList<Student> arrayList) throws Exception {
		// Create serialized stream 
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));
		// Write out object
		oos.writeObject(arrayList);
		// Release resources
		oos.close();
	}
}

3. Precautions

  • 1. Read and write in the same order
  • 2. Serializable is required to implement serialized or deserialized objects
  • 3. It is recommended to add SerialVersionUID to the serialized class To improve version compatibility
  • 4. When serializing an object, all attributes in it are serialized by default, except for members decorated with static or transient
  • 5. When serializing an object, it is required that the type of the attribute inside also implement the serialization interface
  • 6. Serialization is inheritable, that is, if a class has implemented serialization, all its subclasses have implemented serialization by default

5. Standard input / output stream

typeDefault device
System.in standard inputInputStreamkeyboard
System.out standard outputPrintStreammonitor
public class InputAndOutput {
    public static void main(String[] args) {
        //Public final static InputStream in of System class = null;
        // System.in compilation type InputStream
        // System.in run type BufferedInputStream
        // Represents a standard input keyboard
        System.out.println(System.in.getClass());

        //Lao Han's interpretation
        //1. System.out public final static PrintStream out = null;
        //2. Compile type PrintStream
        //3. Operation type: PrintStream
        //4. Indicates standard output display
        System.out.println(System.out.getClass());

        System.out.println("hello, Han Shunping Education~");

        Scanner scanner = new Scanner(System.in);
        System.out.println("Input content");
        String next = scanner.next();
        System.out.println("next=" + next);
    }
}

6. Conversion flow

1. Brief introduction

InputStreamReader and OutputStreamWriter

  • 1. InputStreamReader: subclass of Reader, which can wrap (convert) InputStream (byte stream) into Reader (character stream)
  • 2. OutputStreamWriter: subclass of Writer, which implements wrapping OutputStream (byte stream) into Writer (character stream)
  • 3. When processing plain text data, if using character stream is more efficient and can effectively solve the Chinese problem, it is recommended to convert byte stream into character stream
  • 4. You can specify the encoding format (such as UTF-8, GBK, GB2312, iso8859-1, etc.) when using

2,InputStreamReader

//Convert byte stream FileInputStream to character stream InputStreamReader, and specify the encoding gbk/utf-8
public class InputStreamReader_ {
    public static void main(String[] args) throws IOException {

        String filePath = "e:\\a.txt";
        //unscramble
        //1. Convert FileInputStream to InputStreamReader
        //2. Specify the code gbk
        //InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
        //3. Transfer InputStreamReader to BufferedReader
        //BufferedReader br = new BufferedReader(isr);

        //Put 2 and 3 together
        BufferedReader br = new BufferedReader(new InputStreamReader(
                                                    new FileInputStream(filePath), "gbk"));
        //4. Read
        String s = br.readLine();
        System.out.println("Read content=" + s);
        //5. Turn off the outer flow
        br.close();
    }
}

3,OutputStreamWriter

//Convert FileOutputStream byte stream into character stream OutputStreamWriter
//Specifies the encoding for processing gbk/utf-8/utf8
public class OutputStreamWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "e:\\hsp.txt";
        String charSet = "utf-8";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charSet);
        osw.write("hi, Han Shunping Education");
        osw.close();
        System.out.println("according to " + charSet + " File saved successfully~");
    }
}

7. Print stream

  • Print stream has only output stream and no input stream
public class PrintStream_ {
    public static void main(String[] args) throws IOException {

        PrintStream out = System.out;
        //By default, the location of PrintStream output data is standard output, that is, the display
        /*
             public void print(String s) {
                if (s == null) {
                    s = "null";
                }
                write(s);
            }
         */
        out.print("john, hello");
        //Because the bottom layer of print uses write, we can directly call write to print / output
        out.write("oracle ,Hello".getBytes());
        out.close();

        //We can modify the location / device of print stream output
        //1. Modify the output to "e:\f1.txt"
        //2. "hello, Han Shunping education ~" will be output to e: \ F1 txt
        //3. public static void setOut(PrintStream out) {
        //        checkIO();
        //        setOut0(out); // native method, modified out
        //   }
        System.setOut(new PrintStream("e:\\f1.txt"));
        System.out.println("hello, Han Shunping Education~");
    }
}

8,PrintWriter

public class PrintWriter_ {
    public static void main(String[] args) throws IOException {

        //PrintWriter printWriter = new PrintWriter(System.out);
        PrintWriter printWriter = new PrintWriter(new FileWriter("e:\\f2.txt"));
        printWriter.print("hi, Hello, Beijing~~~~");
        printWriter.close();//flush + close the stream before writing data to the file
    }
}

6,Properties

Common methods for Properties

  • Load: load the key value pair of the configuration file to the Properties object list: display the data to the specified device / flow object
  • getProperty(key): get the value according to the key
  • setProperty(key,value): sets the key value pair to the Properties object
  • Store: store the key value pairs in Properties in the configuration file. In idea, save the information to the configuration file. If it contains Chinese, it will be stored as unicode code
  • http://tool.chinaz.com/tools/unicode.aspx unicode code query tool
public static void main(String[] args) throws IOException {
    //Use the Properties class to create a configuration file and modify the content of the configuration file

    Properties properties = new Properties();
    //establish
    //1. If the file does not have a key, it is created
    //2. If the file has a key, it is modified
    /*
            Properties The parent class is Hashtable, and the bottom layer is the core method of Hashtable
            public synchronized V put(K key, V value) {
                // Make sure the value is not null
                if (value == null) {
                    throw new NullPointerException();
                }
                // Makes sure the key is not already in the hashtable.
                Entry<?,?> tab[] = table;
                int hash = key.hashCode();
                int index = (hash & 0x7FFFFFFF) % tab.length;
                @SuppressWarnings("unchecked")
                Entry<K,V> entry = (Entry<K,V>)tab[index];
                for(; entry != null ; entry = entry.next) {
                    if ((entry.hash == hash) && entry.key.equals(key)) {
                        V old = entry.value;
                        entry.value = value;//If the key exists, replace it
                        return old;
                    }
                }
                addEntry(hash, key, value, index);//If it is a new k, add entry
                return null;
            }
         */
    properties.setProperty("charset", "utf8");
    properties.setProperty("user", "Tom");//Note that when saving, it is the unicode code value in Chinese
    properties.setProperty("pwd", "888888");

    //Store the k-v in a file
    properties.store(new FileOutputStream("src\\mysql2.properties"), null);
    System.out.println("Successfully saved the configuration file~");
}

Keywords: JavaSE

Added by robot43298 on Thu, 23 Dec 2021 08:53:34 +0200