1. For performance considerations, arrays are preferred
Arrays are used less and less frequently in project development, especially in business-oriented development. First of all, arrays do not have many methods provided by collections such as List and Set. You have to write the search and addition algorithms yourself, which is extremely cumbersome and troublesome. However, Since collections such as List and Set use generic support, they are all stored in wrapper classes, and arrays can use basic data types. The execution speed of basic data types is much faster than that of wrapper types, and the bottom layer of the collection class It is also implemented through arrays.
2. If necessary, use variable length arrays
When learning collection classes, many people like to compare the fixed length of the array with the variable length of the collection type, but in fact this comparison is not appropriate. By observing the implementation of collection classes such as ArrayList, we can actually see that the so-called The collection becomes longer. In fact, it just expands the original array in a tactful way.
Copy the code code as follows:
public static T[] expandCapacity(T[] data, int newLength) {
// Determine whether it is a negative value
newLength = newLength < 0 ? 0 : newLength;
// Generate a new array, copy the original value and specify the length
return Arrays.copyOf(data, newLength);
}
When performance requirements are high, you can consider encapsulating arrays. The constant length of the array is not an excuse for us not to use them.
3. Be wary of shallow copies of arrays
Shallow copy of array is also the basis of Java programming. Shallow copy means that when copying an array, the basic type copies the value, while the reference type copies the reference address. In the above example, the array is copied using Arrays.copyOf is a shallow copy, so you need to pay attention when using it.
4. Under clear scenarios, specify the initial capacity for the collection
In our daily use, because the collection type automatically changes in length, the initial value will not be attached to the collection class when creating an object. Let’s take our most commonly used ArrayList as an example. We first need to know that when the collection capacity is reached At the critical point, the underlying array will be The copyOf operation generates a new array, and the capacity of the new array is 1.5 times that of the old array, and the default array length is 10. When we clearly know that the amount of data to be placed in the container is large, we should specify the initial value to avoid excessive Performance overhead caused by using copyOf times
5. Choose the appropriate optimal algorithm
Searching for the maximum or minimum value of data is the most basic knowledge of data structure. We also have many ways to implement it in Java. Here are two algorithms:
Copy the code code as follows:
public static int getMaxByArray(int[] data) {
//The simplest self-implemented search method
int max = data[0];
for (int i = 1, size = data.length; i < size; i++) {
max = max < i ? i : max;
}
return max;
}
Copy the code code as follows:
public static int getMaxByArray(int[] data) {
// Sort first and then get the last bit
Arrays.sort(data);
return data[data.length - 1];
}
6. Basic type array conversion trap!
Please observe the following code
Copy the code code as follows:
public static void main(String[] args) {
int[] nums = new int[] { 1, 2, 3, 4, 5 };
List list = Arrays.asList(nums);
System.out.println(list.size());
//The output size at this time is 1
}
The result we expected was to convert the elements in the array into a collection class through Arrays.asList, but contrary to expectations, we only added the array itself and did not separate the values in the array. At this time, if the collection Adding generics to List will give an error message during compilation, or changing the array itself to Integer can solve the problem.
7. The List object generated by the asList method cannot be changed.
Through the above example, we can see that using the Arrays.asList method can convert an array into a List. So what is special about the List returned by the asList method? Note that the returned List does not support changes because The asList method returns not java.util.ArrayList, but Array A static private internal class in the s tool class, although it has the same parent class AbstractList as ArrayList, but when overriding add and other methods, an UnsupportedOperationException is thrown. This static private internal class only implements size, toArray, Get, contains these methods
8. Use different traversal methods for different data structures
Please watch the following code
Copy the code code as follows:
public static void main(String[] args) {
//The following is the traversal method of the ArrayList collection
int num = 80 * 10000;
List arrayList = new ArrayList(num);
for (int i = 0, size = arrayList.size(); i < size; i++) {
arrayList.get(i);
}
//The following is the traversal method of the LinkedList collection
List linkedList = new LinkedList();
for (Integer integer : linkedList) {
}
}
Why choose different traversal methods for LinkedList and ArrayList?
1. Because ArrayList implements the RamdomAccess interface (random access interface), the RamdomAccess interface is the same marking interface in Java as Serializable and Cloneable interfaces, which means that this class can be randomly accessed. For ArrayList, it means that between data There is no correlation, that is, two adjacent positions have no interdependence relationship and can be accessed randomly.
2. The foreach syntax in Java is a variant usage of iterator (iterator). We know that iterator is one of the 23 design patterns, but the iterator needs to know the time relationship between two elements, otherwise how to provide hasNext support What? It’s because the previous element needs to determine whether the next element exists, and this relationship is forcibly established, which violates the special characteristics of ArrayList random access.
3. In LinkedList, because it is stored in the form of a doubly linked list, the support for iterators is very good. Because there is an inherent relationship between two adjacent elements in LinkedList, different traversal methods must be adopted for LinkedList and ArrayList. Readers who are interested can try accessing LinkedList in the form of subscripts, and will find that there is a big gap in efficiency between the two.
8. Choose ArrayList or LinkedList when appropriate
The main differences between ArrayList and LinkedList:
1. The underlying data structure of ArrayList is an array, while the underlying structure of LinkedList is a doubly linked list.
2. When inserting data, since ArrayList needs to move the array elements backward after each insertion, LinkedList only needs to change the head node and tail node to complete the insertion operation, so when insertion operations are more frequent, LinkedList is preferred.
3. When deleting data, because ArrayList needs to maintain the order of the array, the elements also need to be shifted backward or forward after deletion, while LinkedList still changes the head and tail nodes.
4. When updating, since LinkedList will use a half traversal method to find the positioned element and then update it, compared to ArrayList's direct replacement of positioned subscript elements, ArrayList is more efficient in updating.
5.LinkedList can simulate a queue through operations such as addFirst and addLast of LinkedList.
9. When lists are equal, you only need to care about the element data
In order for us to program interfaces such as List, Set, and Map with peace of mind, Java has overridden equlas in the collection class, so that when comparing whether two collections are equal, we only need to compare whether the element data is equal. This avoids Fixed the erroneous Java code caused by replacing the collection implementation class
Copy the code code as follows:
public static void main(String[] args) {
List arrayList = new ArrayList();
arrayList.add(1);
arrayList.add(2);
List linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
System.out.println(arrayList.equals(linkedList));
// Don't care about the specific implementation, the output is true
}