(6) Java’s built-in tool classes

Java built-in tool classes (String, StringBuffer, LinkedList, ArrayList, HashMap and other tools)

? Java provides a huge number of extremely rich tool classes. For Java learners, through the few classes explained below, they can understand and master the commonality of classes, so as to draw inferences about other cases from one instance and learn by analogy; in particular, they must learn Use program editors and network resources to freely consult relevant information; by writing specific examples, verify the functions of classes and their methods, and then master a class, this is the most important.

The following is divided into two parts. Firstly, the basic tool classes such as String, StringBuffer, StringBuilder, Calendar, and array are described; Tool of.

Article directory

  • Java built-in tool classes (String, StringBuffer, LinkedList, ArrayList, HashMap, etc.)
    • Basic tools
      • String class
      • StringBuffer class and StringBuilder class
      • About the input Scanner class
      • array
        • one-dimensional array
          • About array.length()
        • array’s clone() method and “shallow cloning”
        • Two-dimensional array
      • Calendar class: Calendar
    • Generics Preliminary
    • Advanced Tools
      • ArrayList and LinkedList
        • foreword
        • ArrayList
        • LinkedList
        • ArrayList and LinkedList features and methods
          • 1. The benefits of generics
          • 2. Element positioning method
          • 3. Determine whether the element exists
      • HashMap
        • foreword
        • HashMap()
        • Precautions for use
        • Traversal of HashMap
        • Traversal of HashMap

Basic tool class

String class

“Strings” are “taken seriously” in almost all programming languages; a large number of string manipulation functions or similar facilities are provided. Java is certainly no exception. The following is its most basic usage”

public class AboutString1 {<!-- -->
    //String class
    public static void main(String[] args) {<!-- -->
        //Generation method of string (class) object
        //1, new instantiation
        String str1 = new String("The first generation method");
        //2. Directly assign the initial value (string constant)
        String str2 = "The second generation method";
        //This method is type conversion, and there are many overloaded methods, which are very sharp;
        String str3 = String. valueOf(12300);

        //The length() method of the String class can get the length of the string;
        System.out.println(str1.length());
        //String class provides a lot of methods, making string manipulation more convenient;
        System.out.println(str1.substring(3,5));
        //As mentioned earlier, "String + value" will generate an automatic conversion type...
        System.out.println(str3 + 321);
    }
}

One of the most important declarations about the String class is:

? The value of the String class cannot be modified.

public class AboutString2 {<!-- -->
    public static void main(String[] args) {<!-- -->
        String str = "abcdefg123xy";
        System.out.println(str.replace("123","456"));
        System.out.println(str);
    }
}

Observe the output:

? The str.replace() method is to replace “123” in the source string with “456”. The output seems to have indeed changed the content of str, but the subsequent output clearly indicates that the content of str does not seem to have changed!

? In fact, the result of str.replace() is a new string, which is a new String object.

public class AboutString3 {<!-- -->
    public static void main(String[] args) {<!-- -->
        System.out.println("" + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9);
        String str = "";
        for(int i = 1; i < 100; i ++ ) {<!-- -->
        str + = 1;
        }
        System.out.println(str);
    }
}

The output is:

You should be able to see the operation results in the above figure, all of which are string type data;

The purpose of the fifth line of the program is to let everyone understand that the essence of the fifth line and the eighth line is the same, both are the process of “adding” strings and numeric data to obtain a new string. However, this program is very inefficient, because every time the ninth line is executed, a new String object will be new!

It is also possible to change this inefficiency, but you can no longer use the String class, you need to use the StringBuffer class or StringBuilder class we will introduce next.

StringBuffer class and StringBuilder class

Since the String class is immutable, it is very inefficient to operate with the String type when a large amount of “string patching” is required, and the memory consumption is also high. At this time, we should use our StringBuffer class or StringBuilder class.

These two classes are very similar, and the difference is about thread safety, so I won’t go into details here.

Taking StringBuffer as an example, we give his usage method:

Usually, if the string to be processed is a simple constant, or the string does not change much in the program, then it is better to use String, which is more efficient. If the string will continue to change in the program, then use the StringBuffer class or the StringBuilder class.

About the input Scanner class

? When learning C language, we have been exposed to the input function scanf() very early, but until now we still haven’t mentioned the input in Java. The input in Java needs to use a class Scanner. When we understand the class After the basic concepts, we can learn about Scanner.

? The function of the Scanner class is much more powerful than the scanf() function in C language, and it is relatively complicated to use. First, we need to initialize the Scanner class object in the following form.

 Scanner in = new Scanner(System.in);

Among them, System.in is the “standard input device”, which is the keyboard. When using, we also need to pay attention to the closing operation. That is, by writing at the end of the program:

 in. close();

Our usual method is:

String str = in. next();

The complete program segment is as follows:

Public class AboutScanner {<!-- -->
    public static void main(String[] args) {<!-- -->
    Scanner in = new Scanner(Sysetm.in);
        String str = in. next();
        System.out.println(str);
        in. close();
    }
}

Regarding input control, the Scanner class provides a hasNext***() method, which is usually used with a loop to complete the input of multiple data:

Public class AboutScanner1 {<!-- -->
    public static void main(String[] args) {<!-- -->
    Scanner in = new Scanner(Sysetm.in);
        
        int dataIn;
        while(in.hasNestInt()) {<!-- -->
           dataIn = in. nextInt();
           System.out.println(dataIn);
        }

        in. close();
    }
}

It can be seen that the input of Java is also very easy to use;

Array

One-dimensional array

Arrays are “classes” in Java, which is very different from the arrays in C language we have learned!

So how is the Java array defined? The definition and use of arrays in java? First of all, let’s understand the definition and initialization of arrays in Java:

public class AboutArrar1 {<!-- -->
    public static void main(String[] args) {<!-- -->
        // The first definition method: declare a one-dimensional array: data type [] array name = {data...};
        int [] array1 = {<!-- -->1,2,3,4};
        // The second definition method: declare a one-dimensional array: data type [] array name = new data type [length];
        int[] array2 = new int[10];
        // The third definition method: declare a one-dimensional array: data type array name [];
        double array3[]; //declare array;
        array3 = new double[5]; // allocate memory space
    }
}

? A one-dimensional array can store tens of millions of data, and the types of these data are exactly the same. The above method of use is not fixed. To use a java array, you must declare the array and allocate memory to the array. After the array is declared, the name of the array is actually saved in the stack memory, and then the memory required by the array needs to be configured in the heap memory, and the compiler is notified how many elements the declared array will store, while new is the command to compile The compiler allocates space according to the length in parentheses.

The Java array itself is just a “pointer”. After applying for space through new, before assigning an initial value to the array element, the value of each array element is based on whether it is one of the eight basic types or a class type. Java has its default initial value. value.

The initial value of the eight basic types is 0 (double is 0.0, boolean is false); while the initial value of all class types is null, that is, a null pointer. as follows;

public class AboutArrar1 {<!-- -->
    public static void main(String[] args) {<!-- -->
        int [] array1 = {<!-- -->1,2,3,4};
        for(int i = 0; i < arr1.length; i ++ ) {<!-- -->
            System.out.println(array1[i] + " ");
        }
        
        int[] array2 = new int[10];
        for(int i = 0; i < arr2. length; i ++ ) {<!-- -->
            System.out.println(array2[i] + " ");
        }
        
        String array3[];
        array3 = new String[5];
         for(int i = 0; i < arr3. length; i ++ ) {<!-- -->
            System.out.println(array3[i] + " ");
        }
    }
}

The output is:

About array.length()

? Since the array is a class, then length is a class member, and its meaning is also very clear: the number of array elements (length). The maximum boundary value control of the array subscript is controlled by the length member, which is a method to ensure that “subscript out of bounds” does not occur.

Array’s clone() method and “shallow clone”

The array class provides a clone() method, as the name suggests: clone. This method can “copy” an array.

For example:

public class AboutArrayClone {<!-- -->
    public static void main(String[] args) {<!-- -->
        int[] arr1 = new int[10];
        for(int i = 0; i < arr1. length; i ++ ) {<!-- -->
            arr1[i] = i;
        }
        int[] arr2 = arr1. clone();
        for(int i = 0; i < arr2. length; i ++ ) {<!-- -->
            System.out.println((i == 0 ? "" : ",") + arr2[i]);
        }
    }
}

The output is:

The above code can see the use of clone(). So what is “shallow clone”? That is, arr.clone() just clones the values of each member of arr. If the array elements are not of the eight basic types, then clone() still only clones the values of the array elements;

In fact, that is to say, when arr is initialized, an instance space is applied for each object, and each object is the first address of the applied instance space; the clone() method “clones” only the value of each element of the arr array itself, that is The value of the first address, so the cloned arr array appears to be an array “independent” of arr, but in fact they all point to the same instance space. This is “shallow cloning”.

Two-dimensional array

The essence of a two-dimensional array is also a “class”. Similarly, first understand the basic definition and initialization of two-dimensional arrays:

public class AboutArrar1 {<!-- -->
    public static void main(String[] args) {<!-- -->
    //1. Determine the number of rows and columns of the two-dimensional array by assigning initial values;
        int [][] array1 = {<!-- -->{<!-- -->1,2},{<!-- -->1,2,3},{<!-- -- >1,2,3,4}};
 //2. Determine the number of rows and columns through new;
        int[][] array2 = new int[3][2];
//3. Initialize the rows first, and then initialize the columns row by row;
int[][] array3 = new int[3][];
for(int i = 0; i < array3. length; i ++ ) {<!-- -->
            array3[i] = new int[2];
        }
    }
}

For Java’s two-dimensional array object, its essence is still a pointer, and this pointer should be initialized first to allocate a space for it, and this space is composed of “one-dimensional array objects” and needs to be further initialized. That is as shown below;

How to judge the type of Java array object?

 array.getClass().isArray();

Calendar class: Calendar

? The date type is a powerful tool type provided by many high-level programming languages, through which date data can be processed and output conveniently, and it is widely used in Java programming.

The object initialization method of the Calendar class is very different, and it uses a so-called “factory” mode to initialize the calendar class object:

Calendar today = Calendar. getInstance();
//The getInstance() method is the basic usage of the Calendar class;

The following is an example to explain the basic usage of the Calendar class. How to get the value of year, month, day, week, hour, minute, second and millisecond:

public class AboutCalendar {<!-- -->
    public static void main(String[] args) {<!-- -->
        Calendar today = Calendar. getInstance();
        System.out.println("Year: " + today.get(Calendar.YEAR));
        System.out.println("Month: " + today.get(Calendar.MONTH));
        System.out.println("Day: " + today.get(Calendar.DATE));
        System.out.println("Week: " + today.get(Calendar.DAY_OF_WEEK));
        System.out.println("Hour: " + today.get(Calendar.HOUR));
        System.out.println("minute:" + today.get(Calendar.MINUTE));
        System.out.println("Second: " + today.get(Calendar.SECOND));
        System.out.println("Milliseconds: " + today.get(Calendar.MILLISECOND));
    }
}

Look at the output:

If you want to output into a standard format, you can try it yourself.

Introduction to Generics

What are generics? What is the role of generics in Java?

? Generics are a powerful mechanism provided by Java 1.5, which makes Java programming more flexible and safer. Then why introduce the concept of “generics”?

The specific types of array elements are not determined in the functional requirements. Suppose we limit the types to the eight basic types. Then, based on the knowledge we have learned now, we can use the method of “overloading methods”; but in the process of using it, we will I found that such a solution feels very “stupid”; in order to simplify the handling of this kind of problem, Java proposed the concept of “generics”. The most important thing about generics is:

? Not sure when coding, but sure when running! ?

public class AboutGeneric {<!-- -->
    public static <T> T[] revArray(T[] m) {<!-- -->
        T temp;

        for (int i = 0; i < m.length / 2; i ++ ) {<!-- -->
            temp = m[i];
            m[i] = m[m.length - i -1];
            m[m.length - i -1] = temp;
        }
        return m;
    }
}

In the above program:

? Appears before the return value type of the method, indicating that this method uses generics; in the subsequent code T represents a certain class type; and the specific situation of this class type depends on the specific type of the actual parameter when the method is called Make a judgment.

? It is important to note that generic types can only be class types!

With generics, you can also define generic classes:

public class MyGeneric<T> {<!-- -->
private T member;
\t
public MyGeneric(){<!-- -->
}
    
    public MyGeneric(T memeber){<!-- -->
        this. member = member;
}
    
    public T getMember() {<!-- -->
        return member;
    }
    
    public void setMember(T member) {<!-- -->
        this. member = member;
    }
}

In the above code:

public class MyGeneric<T>

After the class name is the “generic flag”, after which T can be used as a type in the code. In addition, generics can also be multiple:

public class MyGeneric<T, K> {}

Advanced Tools

ArrayList and LinkedList

Foreword

? Array is a common data structure in programming, and the frequency of use is very high. However, arrays have inherent defects, such as the size of the array must be defined in advance, and cannot be changed during use. This makes many problems inconvenient to solve with arrays. There is a similar situation in the C language, and the solution at that time was “linked list”. Using a linked list can avoid the above problems. However, the linked list also has its inconveniences, for example, the programming is complicated, and “random positioning” is not supported.
? In order to solve the above problems, Java provides two highly encapsulated classes: ArrayList and LinkedList. To say that they are “highly encapsulated” means that the internal implementation of these two classes is not simple and the functions are very powerful. However, given The means provided by tool users are very simple and easy to use.
First of all, these two classes both have the suffix of List, which means that both classes are “lists” (actually “arrays”), but their implementation principles are different: ArrayList uses “dynamic arrays” internally, while LinkedList internally Use a “linked list”.
? Second, the basic functionality they provide is similar no matter what they are used internally. It can be considered that these two classes are “dynamic arrays”, which can completely replace the arrays described above.

ArrayList

First, let’s look at a piece of code:

public class AboutArrayList {<!-- -->
    public static void main(String[] args) {<!-- -->
        //Initialize the ArrayList object array
        ArrayList<Integer> array = new ArrayList<>();
        //Increase an int value 10
        array. add(10);
        //Increase an int value 20
        array. add(20);
        // Get the second value whose subscript is 1
        int num = array. get(1);
        System.out.println(num);
    }
}

? The first thing you see is that ArrayList is a generic class that can store data of any specified type.

? The biggest advantage of ArrayList is “dynamic”, you don’t have to care about the size of the array space. ArrayList can adjust the size of the array space according to the actual loaded data. When accessing the values in the array, you can also use the subscript traversal method. as follows

public class AboutArrayList {<!-- -->
    public static void main(String[] args) {<!-- -->
       int[] a = {<!-- -->1,2,3,4,5};
       ArrayList<Integer> array = new ArrayList<>();
        for (int i = 0; i < a.length; i ++ ) {<!-- -->
            array. add(a[i]);
        }

        for (int num : array) {<!-- -->
            System.out.println(num);
        }
    }
}

In the above code,

for (int num : array)

Understanding: “:” is an element before, and the type of the element must be consistent with the generic type of ArrayList; this element is each element in the subsequent array or LIst, and is obtained from the front to the back in the order of subscripts.

The above operations are also the same for LinkedList.

LinkedList

public class AboutLinkedList {<!-- -->
    public static void main(String[] args) {<!-- -->
        LinkedList<Integer> arr = new LinkedList();
        arr. add(42);
        arr.add(777);
        arr.add(1314);
        for (int num : arr) {<!-- -->
            System.out.println(num);
        }
    }
}

? My leader once mentioned “the similarities and differences between arrays and linked lists” in the data structure: arrays are continuous storage structures with high storage space utilization and support for random positioning, but the size of the array space needs to be defined in advance (arrays for dynamic space applications) It is also necessary to determine the size when applying for space); the linked list is a non-continuous storage structure, and the storage space utilization rate is not as high as that of the array. It is O(n); for the operation of insertion and deletion, the complexity of the linked list is constant, which can be considered as O(1).

? The above statement shows that if there is basically no data insertion and deletion in the future program, and the main thing is to search, then ArrayList is more efficient; otherwise, LinkedList is more efficient.

ArrayList and LinkedList features and methods

1. The benefits of generics

Both ArrayList and LinkedList are generic classes, which makes both “containers” convenient for storing and processing any type of data.

2. Element positioning method

The indexOf() method is a method provided by both ArrayList and LinkedList, which can obtain the subscript of the specified element.

 public static void main(String[] args) {<!-- -->
        LinkedList<Complex> complexLinkedList = new LinkedList();
        complexLinkedList.add(new Complex());
        complexLinkedList.add(new Complex(1));
        complexLinkedList.add(new Complex(4,2));
        complexLinkedList.add(new Complex(7,7));

        for (Complex complex : complexLinkedList) {<!-- -->
            System.out.println(complex);
        }
        Complex c = new Complex(4,2);
        int index = complexLinkedList. indexOf(c);
        System.out.println(index);
    }
}

The output is:

The output of indexOf() is: 2;

Here is a problem to pay attention to: the equals() method of the Complex class.
The key to the successful positioning of the above program is that in the Complex class, we override the equals() method. And this method is automatically called during the execution of the indexOf() method to determine whether it is “equal”. What would happen if we didn’t override the equals() method?
First of all, no matter whether we override the equals() method or not, the indexOf() method will automatically call the equals() method for “equal” judgment! It’s just that, in the absence of coverage, the original equals() method of the Object class is called, and its “equal” comparison principle is “equal address” (because the essence of the object is a pointer!).

If we annotate the equals() method in the Complex() class, when the above code is executed, the original equals() method of the Object class will be called. At this time, the comparison is whether the first addresses are equal, so the return value is -1;

3. Determine whether the element exists

It is also very useful to determine whether a certain value exists in the array.

ArrayList and LinkedList have special implementation methods: contains() method;

public class AboutLinkedList {<!-- -->
    public static void main(String[] args) {<!-- -->
        Complex c = new Complex(4,2);
        LinkedList<Complex> complexLinkedList = new LinkedList();

        complexLinkedList.add(new Complex());
        complexLinkedList.add(new Complex(1));
        complexLinkedList.add(new Complex(4,2));
        complexLinkedList.add(new Complex(7,7));

        System.out.println(complexLinkedList.contains(c));
    }
}

The return value is of course true;

If the equals() method in Complex() is commented here, the result will be the same as the indexOf() method above, and the reason is the same.

Complex() Complex class implementation process and code: https://blog.csdn.net/SwaggerHB/article/details/129735124

HashMap

Foreword

? We know that the “unique number” of life and work activities in the real society is a very broad application scenario and a common means of managing people, things, and things. For example, everyone has an ID number, college students have a student number, vehicles have a number plate, and books have a book number… These “unique” numbers correspond to a (class) unique entity. There is a relationship between ID and entity: Key-value pair (Key – Value)
? (Key-Value), that is, key-value pairs, is also a data form that is widely used in programming. Among the many tool classes provided by Java, there is a class that is specially designed to deal with “key-value pairs” of. There are many such classes, here we focus on one class: the HashMap class.

HashMap()

? HashMap is a double generic class, because it deals with key-value pairs, of course, it involves two types of data.

? The following program shows the basic usage of HashMap:

public class AboutHashMap {<!-- -->
    public static void main(String[] args) {<!-- -->
        //Initialize the HashMap object nameMap
        HashMap<String, String > nameMap = new HashMap<>();
        //Add a key-value pair whose key-value type is String type
        nameMap.put("7076","Bo Huang");
        nameMap.put("7077","Zhang San");
        nameMap.put("7078","Li Si");
        nameMap.put("7079","Wang Mazi");
        nameMap.put("7080","Chen Sledgehammer");

//Get the corresponding value according to the key of "7076"
        String name = nameMap. get("7076");
        System.out.println(name);
    }

The HashMap class is the same as other classes, and its objects also need to be new first; the most commonly used method of the HashMap class: put() is used to “store” a key-value pair; another commonly used method: get() is used to retrieve according to the “key” The value corresponding to the key. Just like the above program and its execution result.

Precautions for use

1. Keys cannot be repeated;
The general execution process inside the put(key, value) method is: first find out whether the key already exists; if it does not exist, add the key-value pair; if it already exists, replace the original value with the value provided by the parameter.

2. The value can be repeated, even null;

3. Traversal and disorder;
Unlike ArrayList and LinkedList, HashMap does not record the “input order” information when storing key-value pairs, so key-value pairs are unordered in HashMap. This conclusion can be verified by traversing the key-value pairs stored in the HashMap.
There are many methods for traversing HashMap, the most commonly used is key traversal;

4. Efficiency issues:

? The HashMap class is proposed in “Advanced Tool Classes” because HashMap can not only handle “key-value pairs”, a storage structure that is often used in advanced Java programming in the future, but also because of its excellent performance, it can greatly optimize the program time complexity!
? In the implementation process of HashMap, after the number of key-value pairs is greater than 16 groups, the efficient data structure of “red-black tree” is adopted. (The red-black tree is a “self-balancing binary search tree”, and the worst-case time complexity of insertion, deletion, and search is O(logN). When the amount of key-value pairs is very large, the operation Efficiency is particularly prominent!)

HashMap traversal

 public void showNameMap(HashMap<String, String> nameMap) {<!-- -->
        for (String key : nameMap.keySet()) {<!-- -->
            String value = nameMap. get(key);
            System.out.println("key: " + key + "value: " + value);
        }
    }

Maps are unordered. This conclusion can be verified by traversing the key-value pairs stored in the HashMap.
There are many methods for traversing HashMap, the most commonly used is key traversal;

4. Efficiency issues:

? The HashMap class is proposed in “Advanced Tool Classes” because HashMap can not only handle “key-value pairs”, a storage structure that is often used in advanced Java programming in the future, but also because of its excellent performance, it can greatly optimize the program time complexity!
? In the implementation process of HashMap, after the number of key-value pairs is greater than 16 groups, the efficient data structure of “red-black tree” is adopted. (The red-black tree is a “self-balancing binary search tree”, and the worst-case time complexity of insertion, deletion, and search is O(logN). When the amount of key-value pairs is very large, the operation Efficiency is particularly prominent!)

HashMap traversal

 public void showNameMap(HashMap<String, String> nameMap) {<!-- -->
        for (String key : nameMap.keySet()) {<!-- -->
            String value = nameMap. get(key);
            System.out.println("key: " + key + "value: " + value);
        }
    }