Java programming logic (31) - analysis Arrays

An array is a data structure stored a plurality of basic elements of the same type, the array elements stored in consecutive memory, any element can be positioned directly through the array subscripts, we other containers described in subsequent sections, the efficiency is very high compared.

Array operations is a common basic operation of a computer program, there is a class in Java Arrays, contains static methods for array operations. This section we will discuss these methods, let's look at how to use, and then look at their implementation principle . Learning Arrays usage, we can avoid reinventing the wheel, directly, learn its implementation principle, we can when needed, to realize it does not have its own function.

usage

Arrays string toString method can be conveniently output in an array, for easy viewing, which has nine overloaded methods, including an array of eight basic types of objects and an array type, where two include:

public static String toString(int[] a)
public static String toString(Object[] a) 

E.g:

int[] arr = {9,8,3,4};
System.out.println(Arrays.toString(arr));

String[] strArr = {"hello", "world"};
System.out.println(Arrays.toString(strArr));

Output

[9, 8, 3, 4]
[hello, world]

Without the use of Arrays.toString, the output of the array itself directly, i.e. change the code to:

int[] arr = {9,8,3,4};
System.out.println(arr);

String[] strArr = {"hello", "world"};
System.out.println(strArr);

The output becomes as follows:

[I@1224b90
[Ljava.lang.String;@728edb84

This output will be difficult to read after @ digital representation of the memory address.

Sorting an array - basic types

Sorting is a very common operation, like toString, each of the basic types of arrays, Arrays, have the sort method (except Boolean), such as:

public static void sort(int[] a)
public static void sort(double[] a)

Sorted by row in ascending order from small to large, see example:

int[] arr = {4, 9, 3, 6, 10};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));

The output is:

[3, 4, 6, 9, 10]

The array is already sorted.

sort can also accept two parameters, the elements are sorted in a specified range, such as:

public static void sort(int[] a, int fromIndex, int toIndex)

FromIndex position including elements, not including elements toIndex position, such as:

int[] arr = {4, 9, 3, 6, 10};
Arrays.sort(arr,0,3);
System.out.println(Arrays.toString(arr));

The output is:

[3, 4, 9, 6, 10]

Just sort of the first three elements.

Sorting an array - object type

In addition to the basic type, sort further object types can be accepted, but the need to achieve objects Comparable interface.

public static void sort(Object[] a)
public static void sort(Object[] a, int fromIndex, int toIndex) 

We look at an example of an array of String:

String[] arr = {"hello","world", "Break","abc"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));

The output is:

[Break, abc, hello, world]

"Break" the reason why at the top, because the uppercase letters are less than lowercase letters. If you want that sort of ignore case when it?

Sorting an array - Custom comparator

There is another sort two overloads, a comparator can accept as a parameter:

public static <T> void sort(T[] a, Comparator<? super T> c)
public static <T> void sort(T[] a, int fromIndex, int toIndex,
                                Comparator<? super T> c)

T represents a method declaration of generics, generics we'll introduce in later chapters, shown here it is that this method can support all object types, as long as the transfer of this type corresponding comparator on it. Comparator is a comparator, which is an interface definition is:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

Compare this method is most important, it compares two objects, the return value represents a result of comparison, o2,0 represents less than -1 means o1 equal, greater than 1 indicates o1 o2.

Sorting is accomplished by comparing the, sort of method in the sort process, the time required for the object to be compared, call compare method comparator.

The String class has a public static member, omit sensitive comparator:

public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                     = new CaseInsensitiveComparator();

We come back to the top of the String array sorting through this comparator:

String[] arr = {"hello","world", "Break","abc"};
Arrays.sort(arr, String.CASE_INSENSITIVE_ORDER);
System.out.println(Arrays.toString(arr));

In this way, ignores the case, the output becomes:

[abc, Break, hello, world]

To further understand Comparator, we look at the String of this comparator is mainly realize code:

Copy the code
private static class CaseInsensitiveComparator
        implements Comparator<String> {
    public int compare(String s1, String s2) {
        int n1 = s1.length();
        int n2 = s2.length();
        int min = Math.min(n1, n2);
        for (int i = 0; i < min; i++) {
            char c1 = s1.charAt(i);
            char c2 = s2.charAt(i);
            if (c1 != c2) {
                c1 = Character.toUpperCase(c1);
                c2 = Character.toUpperCase(c2);
                if (c1 != c2) {
                    c1 = Character.toLowerCase(c1);
                    c2 = Character.toLowerCase(c2);
                    if (c1 != c2) {
                        // No overflow because of numeric promotion
                        return c1 - c2;
                    }
                }
            }
        }
        return n1 - n2;
    }
}
Copy the code

The code is relatively straightforward, it is not explained.

The default sort is ascending order, from largest to smallest row if you want to follow it? For the type of object, you can specify a different Comparator, can be implemented Comparator anonymous inner classes, such as can be:

Copy the code
String[] arr = {"hello","world", "Break","abc"};
Arrays.sort(arr, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o2.compareToIgnoreCase(o1);
    }
});
System.out.println(Arrays.toString(arr));
Copy the code

Program output is:

[world, hello, Break, abc]

Code uses an anonymous inner class Comparator interface, returns o1 o2 and case-insensitive comparison result, so that can be achieved, ignoring case and sorted from largest to smallest. Why o2 and o1 than to reverse it? Because the default is o1 and o2 ratio.

Collections class has two static methods can return the reverse Comparator, such as

public static <T> Comparator<T> reverseOrder()
public static <T> Comparator<T> reverseOrder(Comparator<T> cmp)

About Collections class, we'll introduce in detail in later chapters.

Thus, the code above case ignore string may instead Decommitment:

String[] arr = {"hello","world", "Break","abc"};
Arrays.sort(arr, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(arr));

Comparator comparator transmitted to the sort method, embodied in programming an important way of thinking, and the constant change in phase separation, sorting algorithm and the basic steps are the same, but vary according to what sort, the sort method the same logic as the main algorithm design, and the design parameters for the sort of change that allows the caller to specify dynamic, which is a common design pattern that has a name, called the strategy pattern, a different sort is different strategy.

Binary search

Arrays contains many lookup method and sort corresponding to, may be a binary search in the sorted array, the so-called binary search is from the middle to find, if less than the intermediate element, the upper part looking forward, or looking in the second half, each comparator once, either find, or the look reduced by half, so look for efficiency is very high.

Binary search for either primitive array for the object may be an array, the array of objects may be transferred Comparator, can also be specified search range, as shown below:

For int array

public static int binarySearch(int[] a, int key)
public static int binarySearch(int[] a, int fromIndex, int toIndex,
                                       int key)

For an array of objects

public static int binarySearch(Object[] a, Object key)

Custom comparator

public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) 

If you can find, binarySearch return element index to find, for example:

int[] arr = {3,5,7,13,21};
System.out.println(Arrays.binarySearch(arr, 13));

Output is 3. If not found, returns a negative number, the negative number is equal to the insertion point :-( +1), the insertion point said that if the insert elements not found in this location, you can keep the original orderly array, for example:

int[] arr = {3,5,7,13,21};
System.out.println(Arrays.binarySearch(arr, 11));

Output -4, showing the insertion point 3, if the insert 11 at index position 3 can be kept ordered array, i.e., array becomes: {3,5,7,11,13,21}

Note that, binarySearch for the array must be sorted, if the Comparator specified when ordering needs and consistent with the specified Comparator In addition, if there are multiple elements in the array match, which is uncertain returns.

Array copy

And toString, there are also many overloads, such as:

public static long[] copyOf(long[] original, int newLength)
public static <T> T[] copyOf(T[] original, int newLength)

Behind that is a generic usage, shown here is that this method can support all object types, the parameters of what array type, returns the result is what array type.

newLength represents the length of the new array, if the array is greater than the original, the element values ​​back to the default values. Recall default value for the type, a value of 0 for boolean, value is false, for char, a value of '\ 0', for the object, is null.

Look at an example:

String[] arr = {"hello", "world"};
String[] newArr = Arrays.copyOf(arr, 3);
System.out.println(Arrays.toString(newArr));

The output is:

[hello, world, null]

In addition copyOf method copyOfRange Arrays, there are methods to support element copies the specified range, such as:

public static int[] copyOfRange(int[] original, int from, int to)

Represents the index to be copied from the first element, the length of the new array is to-from, to be greater than the length of the original array, if more than, with copyOf Similarly, the multi-position to the default values.

Look at an example:

int[] arr = {0,1,3,5,7,13,19};
int[] subArr1 = Arrays.copyOfRange(arr,2,5);
int[] subArr2 = Arrays.copyOfRange(arr,5,10);
System.out.println(Arrays.toString(subArr1));
System.out.println(Arrays.toString(subArr2));

The output is:

[3, 5, 7]
[13, 19, 0, 0, 0]

subArr1 subarray is normal, to the array length greater than the original copy subArr2, the latter value is set to 0.

Array Comparisons

Primitive objects and object types, as follows:

public static boolean equals(boolean[] a, boolean[] a2)
public static boolean equals(double[] a, double[] a2)
public static boolean equals(Object[] a, Object[] a2)

Only array of the same length, and each element are the same, it returns true, otherwise false. For an object, it refers to the same return true equals.

Padding value

Arrays contains many fill methods, may be provided for each element of the array a same value:

public static void fill(int[] a, int val)

You may be given to each element of the array in a given range of set a same value:

public static void fill(int[] a, int fromIndex, int toIndex, int val)

For example:

int[] arr = {3,5,7,13,21};
Arrays.fill(arr,2,4,0);
System.out.println(Arrays.toString(arr));

The index is set from 2 (including 2) to 4 (excluding 4) elements is 0, the output is:

[3, 5, 0, 0, 21]

Hash value

For arrays, hashes of an array:

public static int hashCode(int a[]) 

String hashCode calculation algorithms and are similar, we look at the code:

Copy the code
public static int hashCode(int a[]) {
    if (a == null)
        return 0;

    int result = 1;
    for (int element : a)
        result = 31 * result + element;

    return result;
}
Copy the code

Recall, String hashCode calculation algorithm is similar, each element in the array affect the hash value, different positions, different impact, using 31 hand generated hash value is more dispersed, on the other hand is relatively high computational efficiency .

Multidimensional Arrays

Before we introduce arrays are one-dimensional arrays can also be multidimensional, first look at two-dimensional array, such as:

Copy the code
int[][] arr = new int[2][3];
for(int i=0;i<arr.length;i++){
    for(int j=0;j<arr[i].length;j++){
        arr[i][j] = i+j;
    }
}
Copy the code

arr is a two-dimensional array, the first dimension of length 2, 3 of the second length dimension, similar to a rectangular matrix, or a similar table, the first row represents a dimension, a second dimension represents the column. ARR [i] denotes the i-th row, which is itself an array, ARR [i] [j] denotes the i-th row j-th element.

In addition to two-dimensional array can also be 3D, 4D and so on, but in general, rarely used more three-dimensional array, there are several dimensions, there are a few [], for example, a three-dimensional array declaration is:

int[][][] arr = new int[10][10][10];

When creating an array, in addition to the length dimension of the first outer specify, no need to specify the length of the other dimensions, and even the first dimension, the second dimension is the length of each element may not be the same, see example:

int[][] arr = new int[2][];
arr[0] = new int[3];
arr[1] = new int[5];

arr is a two-dimensional array, the first dimension of length 2, the second dimension is the length of the first element 3, while the second is 5.

Multi-dimensional array in the end what is it? In fact, it is considered a multidimensional array is just an illusion, only one-dimensional array, but the array each element can also be an array, thus forming a two-dimensional array, if each element is also an array that is three-dimensional array.

Operating a multi-dimensional array

Methods for multidimensional arrays Arrays of toString, equals, hashCode has a corresponding:

public static String deepToString(Object[] a)
public static boolean deepEquals(Object[] a1, Object[] a2)
public static int deepHashCode(Object a[])

DeepXXX these methods, the parameters will be determined whether an array element, and if so, operates recursively.

Look at an example:

Copy the code
int[][] arr = new int[][]{
        {0,1},
        {2,3,4},
        {5,6,7,8}
};
System.out.println(Arrays.deepToString(arr));
Copy the code

The output is:

[[0, 1], [2, 3, 4], [5, 6, 7, 8]]

The principle

hashCode implementations that we have introduced, fill and equals implementations are simple cycle operation only, not go into details.

toString implementation is very simple, use the StringBuilder, we columns under the code, but is not explained.

Copy the code
public static String toString(int[] a) {
    if (a == null)
        return "null";
    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";

    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        b.append(a[i]);
        if (i == iMax)
            return b.append(']').toString();
        b.append(", ");
    }
}
Copy the code

copy

copyOf and copyOfRange use of System.arraycopy, the logic is very simple, we simply listed under the code:

Copy the code
public static int[] copyOfRange(int[] original, int from, int to) {
    int newLength = to - from;
    if (newLength < 0)
        throw new IllegalArgumentException(from + " > " + to);
    int[] copy = new int[newLength];
    System.arraycopy(original, from, copy, 0,
                     Math.min(original.length - from, newLength));
    return copy;
} 
Copy the code

Binary search

Binary search binarySearch code is relatively straightforward, the main code is as follows:

Copy the code
private static <T> int binarySearch0(T[] a, int fromIndex, int toIndex,
                                     T key, Comparator<? super T> c) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        T midVal = a[mid];
        int cmp = c.compare(midVal, key);
        if (cmp < 0)
            low = mid + 1;
        else if (cmp > 0)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}
Copy the code

Two flags are low and high, it indicates Look, while loop, compared with the intermediate value is greater than the find (low increase) in the latter half, or find the front half portion (reduced high).

Sequence

Finally, we look at sorting methods sort, compared with the previous these simple and direct method, sort much more complex, ordering a computer program in a very important aspect, for decades, computer scientists and engineers have done a lot research, design and implement a variety of algorithms to achieve, a lot of optimization. In general, there is no so-called best algorithms, different algorithms often have different suitable occasions.

Arrays of that sort is how to achieve it?

The basic type of array, the algorithm uses a Java double pivot quicksort (Dual-Pivot Quicksort), the algorithm is introduced in Java 1.7, prior to this, the algorithm uses a conventional Java quick sort, quicksort double pivot It is optimized for fast sorting, code that implements the new algorithm is located in java.util.DualPivotQuicksort class.

For the object type, the algorithm uses a Java TimSort, TimSort also introduced in Java 1.7, before that, Java is used in merge sort, TimSort actually a series of optimized merge sort, TimSort implementation code in your class java. util.TimSort in.

In the sorting algorithm, if the length of the array is relatively small, they also use more efficient insertion sort.

Why basic types and object types of algorithms are not the same? Sorting algorithm has a concept of stability, stability is the so-called elements of the same value, if the pre-sorting and sorting algorithm can guarantee their relative order of the same, that the algorithm is stable, otherwise it is unstable.

Quick Sort faster, but unstable, and merge sort is stable. For basic types, the same value is identical, stable unstable does not matter. But for the object type, just the same as the comparison result, they are still different objects, other instance variables are not necessarily the same, it is very stable and unstable relationships may, so using merge sort.

Implementation of these algorithms are more complex, but fortunately, Java provides us with a good realization, in most cases, we will use it.

More ways

In fact, an array of methods Arrays included is relatively small, not a lot of common operations, such as, Arrays of binarySearch can only be ordered for the lookup array, that is not sorted array how easy to find it?

There is an open source Apache package (http://commons.apache.org/proper/commons-lang/), which has a class ArrayUtils (located at the packet org.apache.commons.lang3), which achieve a more common array operations here are some examples, with similar Arrays, each operation has a lot of overloaded methods, we'll only list a.

Flip the array elements

public static void reverse(final int[] array)

For primitive array, Arrays of the sort only from small to large, from large to small, if desired, can be sorted using a reverse flip.

Finding Elements

Copy the code
// scratch back to find 
public static int indexOf (Final int [] Array, Final int valueToFind) 

// looking from the rear forward 
public static int lastIndexOf (Final int [] Array, Final int valueToFind) 

// Check if the containing element 
public static boolean contains (final int [] array, final int valueToFind)
Copy the code

Removing elements

Because the length of the array is fixed, deletion is achieved by creating a new array, and then copy the other elements in addition to delete elements.

Copy the code
// delete the specified positions of elements 
public static int [] Remove (Final int [] Array, Final int index) 

// delete the specified positions of a plurality of elements 
public static int [] removeAll (final int [] array, final int .. . indices) 

// delete the element value element, just delete the first 
public static boolean [] removeElement (final boolean [] array, final boolean element)
Copy the code

Adding elements

As with the deletion, because the array length is fixed, added is achieved by creating a new array, and then copy the contents of the original and new array elements.

Copy the code
// add an element 
public static int [] the Add (Final int [] Array, int Final Element) 

// add an element to the specified position 
public static int [] add (final int [] array, final int index, final int element ) 

// merge the two arrays 
public static int [] addAll (final int [] array1, final int ... array2)
Copy the code

Determine whether the array is sorted

public static boolean isSorted(int[] array) 

summary

In this section we analyze the Arrays class, introduced its usage, as well as the basic principles to achieve, at the same time, we introduced the multi-dimensional arrays as well as in Apache ArrayUtils class. For sorting method with Comparator parameter we mentioned, this is a way of thinking and design patterns, it is worth learning.

An array is a basic data structure in a computer program, Arrays, and ArrayUtils class class encapsulates common operations on the array, using these methods it!

The next section, we look at a computer program, another common operation is the operation to date.

 

Guess you like

Origin www.cnblogs.com/ivy-xu/p/12388819.html