Java object-oriented (X)

Arrays commonly used class of

java.util.Arrays tool class is a class provided by the JDK, various methods for processing the array, and each method are basically static method, it can be called directly by the class name Arrays.

1、asList

Returned by the specified array of fixed-size list.

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

Note: This method returns an ArrayList is not our usual collection classes java.util.ArrayList. Arrays ArrayList here is an internal class java.util.Arrays.ArrayList.

This inner class has the following attributes and methods:

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }

    @Override
    public int size() {
        return a.length;
    }

    @Override
    public Object[] toArray() {
        return a.clone();
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        int size = size();
        if (a.length < size)
            return Arrays.copyOf(this.a, size,
                                 (Class<? extends T[]>) a.getClass());
        System.arraycopy(this.a, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

    @Override
    public E get(int index) {
        return a[index];
    }

    @Override
    public E set(int index, E element) {
        E oldValue = a[index];
        a[index] = element;
        return oldValue;
    }

    @Override
    public int indexOf(Object o) {
        E[] a = this.a;
        if (o == null) {
            for (int i = 0; i < a.length; i++)
                if (a[i] == null)
                    return i;
        } else {
            for (int i = 0; i < a.length; i++)
                if (o.equals(a[i]))
                    return i;
        }
        return -1;
    }

    @Override
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

    @Override
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator(a, Spliterator.ORDERED);
    }

    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        for (E e : a) {
            action.accept(e);
        }
    }

    @Override
    public void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        E[] a = this.a;
        for (int i = 0; i < a.length; i++) {
            a[i] = operator.apply(a[i]);
        }
    }

    @Override
    public void sort(Comparator<? super E> c) {
        Arrays.sort(a, c);
    }
}

(1) ArrayList returned array is a fixed-length list, we can only view or modify it, but can not add or delete

We have found through the source code is not the class add () or remove () this way, if add or delete them, will call the parent class AbstractList corresponding method, and the method will eventually traced the parent class throws UnsupportedOperationException abnormal.

String[] str = {"a","b","c"};
List<String> listStr = Arrays.asList(str);
listStr.set(1, "e");                    // 可以进行修改
System.out.println(listStr.toString()); // [a, e, c]
listStr.add("a");                       // 添加元素会报错 java.lang.UnsupportedOperationException 

(2) the difference between reference arrays and arrays of the basic types of type

String[] str = { "a", "b", "c" };
List listStr = Arrays.asList(str);
System.out.println(listStr.size()); // 3

int[] i = { 1, 2, 3 };
List listI = Arrays.asList(i);
System.out.println(listI.size());   // 1

The above results of the first listStr.size () = 3, and the second listI.size () = 1.

We look at the source code, in Arrays.asList, the method statement for List asList (T ... a). The method receives a variable parameter, the variable parameter, and as a generic type parameter. We know the basic data types can not be used as a generic parameter, but the array is a reference type, so the array can be generified, so int [] parameter type as a whole, rather than as an argument int type.

Therefore, the above method of the generic completion should be:

String[] str = { "a", "b", "c" };
List<String> listStr = Arrays.asList(str);
System.out.println(listStr.size());     // 3

int[] i = { 1, 2, 3 };
List<int[]> listI = Arrays.asList(i);   // 注意这里List参数为 int[] ,而不是 int
System.out.println(listI.size());       // 1

Integer[] in = { 1, 2, 3 };
List<Integer> listIn = Arrays.asList(in);   // 这里参数为int的包装类Integer,所以集合长度为3
System.out.println(listIn.size());      // 3

(3) a list of the elements inside the ArrayList returned is a reference, not independent objects

String[] str = { "a", "b", "c" };
List<String> listStr = Arrays.asList(str);
// 执行更新操作前
System.out.println(Arrays.toString(str));// [a, b, c]
listStr.set(0, "d");// 将第一个元素a改为d
// 执行更新操作后
System.out.println(Arrays.toString(str));// [d, b, c]

We look to modify the contents of the collection, the original contents of the array also changed, so here is a reference type passed.

(4) the known array data, how to quickly get a list of additions and deletions to check the List?

String[] str = { "a", "b", "c" };
List<String> listStr = new ArrayList<>(Arrays.asList(str));
listStr.add("d");
System.out.println(listStr.size()); // 4

(5) Arrays.asList () method Scene

Arrays utility class provides a method asList, the method may use a parameter or variable length arrays converted List. However, the resulting length is fixed List; operation can be modified (for example, changing a location of elements); can not perform (e.g., add, remove other operations) on the length, or throw an UnsupportedOperationException.

So Arrays.asList more suitable for those who already have an array of data, or some of the elements needed to quickly build a List, only for read operations, without adding or deleting scenes operations.

2、sort

This method is used to sort the array, a series of the process is overloaded methods in class Arrays can be seven kinds of basic data types, including byte, char, double, float, int, long, short, etc. can be sorted, there Object type (implement the Comparable interface), and a comparator comparator.

(1) an array of basic types of

int[] num = { 1, 3, 8, 5, 2, 4, 6, 7 };
Arrays.sort(num);
System.out.println(Arrays.toString(num));// [1, 2, 3, 4, 5, 6, 7, 8]

(2) an array of object type

This type of array can be implemented Comparable interface sort, sort override compareTo method.

String[] str = { "a", "f", "c", "d" };
Arrays.sort(str);
System.out.println(Arrays.toString(str));// [a, c, d, f]

String type implements Comparable interface, the internal compareTo method is compared according to the dictionary codes.

Does not implement Comparable interface, can be achieved through Comparator sort

class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

public class Test {
    public static void main(String[] args) {
        Person[] p = new Person[] { new Person("zhangsan", 22), new Person("wangwu", 11), new Person("lisi", 33) };
        Arrays.sort(p, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                if (o1 == null || o2 == null) {
                    return 0;
                }
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println(Arrays.toString(p));
    }
}

3、binarySearch

Find an element in the array with a dichotomy. The method and the same sort methods, applicable to various objects and basic data types.

Note: The dichotomy is an ordered array to find (such as the first sort with Arrays.sort (), then call this method to find). Found subscript element returns, without or -1

int[] num = { 1, 3, 8, 5, 2, 4, 6, 7 };
Arrays.sort(num);
System.out.println(Arrays.toString(num));// [1, 2, 3, 4, 5, 6, 7, 8]
System.out.println(Arrays.binarySearch(num, 2));// 返回元素的下标 1

Specific source code implementation:

public static int binarySearch(int[] a, int key) {
    return binarySearch0(a, 0, a.length, key);
}

private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {
    int low = fromIndex;
    int high = toIndex - 1;
    
    while (low <= high) {
        int mid = (low + high) >>> 1;//取中间值下标
        int midVal = a[mid];//取中间值
        
        if (midVal < key)
        low = mid + 1;
        else if (midVal > key)
        high = mid - 1;
        else
        return mid; 
    }
    return -(low + 1); 
}

4, copyOf and copyOfRange

(1)copyOf

Copy array elements. So the copy has the specified length. Using bottom System.arraycopy () implemented, which is a native method.

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

eg

String[] str = { "1", "2", "5", "3", "4" };
str = Arrays.copyOf(str, 10);
System.out.println(Arrays.toString(str));

(2)copyOfRange

将指定数组的指定范围复制到一个新数组。 底层采用 System.arraycopy()实现。

5、equals 和 deepEquals

(1)equals

equals 用来比较两个数组中对应位置的每个元素是否相等。

八种基本数据类型以及对象都能进行比较。

我们先看看 int类型的数组比较源码实现:

public static boolean equals(int[] a, int[] a2) {
    if (a==a2)//数组引用相等,则里面的元素一定相等
        return true;
    if (a==null || a2==null)//两个数组其中一个为null,都返回false
        return false;

    int length = a.length;
    if (a2.length != length)//两个数组长度不等,返回false
        return false;

    for (int i=0; i<length; i++)//通过for循环依次比较数组中每个元素是否相等
        if (a[i] != a2[i])
            return false;

    return true;
}

在看对象数组的比较:

public static boolean equals(Object[] a, Object[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;

    int length = a.length;
    if (a2.length != length)
        return false;

    for (int i=0; i<length; i++) {
        Object o1 = a[i];
        Object o2 = a2[i];
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }

    return true;
}

(2)deepEquals

也是用来比较两个数组的元素是否相等,不过 deepEquals 能够进行比较多维数组,而且是任意层次的嵌套数组。

String[][] name1 = { { "G", "a", "o" }, { "H", "u", "a", "n" }, { "j", "i", "e" } };
String[][] name2 = { { "G", "a", "o" }, { "H", "u", "a", "n" }, { "j", "i", "e" } };
System.out.println(Arrays.equals(name1, name2));        // false
System.out.println(Arrays.deepEquals(name1, name2));    // true

6、fill

该系列方法用于给数组赋值,并能指定某个范围赋值。

源码分析:

// 给a数组所有元素赋值 val
public static void fill(int[] a, int val) {
    for (int i = 0, len = a.length; i < len; i++)
        a[i] = val;
}

// 给从 fromIndex 开始的下标,toIndex-1结尾的下标都赋值 val,左闭右开
public static void fill(int[] a, int fromIndex, int toIndex, int val) {
    rangeCheck(a.length, fromIndex, toIndex);// 判断范围是否合理
    for (int i = fromIndex; i < toIndex; i++)
        a[i] = val;
}

7、toString 和 deepToString

toString 用来打印一维数组的元素,而 deepToString 用来打印多层次嵌套的数组元素。

源码分析:

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(", ");
    }
}

本文借鉴处:https://www.cnblogs.com/ysocean/p/8616122.html

Guess you like

Origin www.cnblogs.com/xzh0717/p/11297566.html