Javaオブジェクト指向(X)

配列は一般のクラスを使用します

java.util.ArraysツールクラスがJDKによって提供されるクラスであり、アレイ、および各メソッドを処理するための種々の方法は、基本的に静的メソッドであり、それはクラス名アレイによって直接呼び出すことができます。

1、asList

固定サイズのリストの指定された配列によって返されます。

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

注:このメソッドは、ArrayListのがいつものコレクションクラスのjava.util.ArrayListのではありません返します。配列は、ここでのArrayList内部クラスjava.util.Arrays.ArrayListです。

この内部クラスは以下の属性とメソッドがあります。

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のアレイが、我々はそれだけを固定長のリスト表示または変更することができますされて返されますが、追加または削除することはできません

私たちは、ソースコードを発見したことは、クラスの追加()または追加したり削除したり、メソッドを、対応する親クラスAbstractListを呼ぶ場合、)(この方法を削除しないで、そしてこの方法は、最終的には親クラスがUnsupportedOperationExceptionをスロートレースします例外。

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)タイプの基本的なタイプの基準アレイとアレイとの間の差を

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

最初listStr.size()= 3、及び第listI.size()= 1上記の結果。

私たちはは、Arrays.asList、方法についての声明では、ソースコードを見て リスト asList(T ... a)です。この方法は、変数、パラメータ、変数、パラメータ、およびジェネリック型パラメータとを受信します。私たちは、基本データ型は、一般的なパラメータとして使用することはできません知っているが、配列は参照型なので、配列を汎用化することができ、全体としてではなく、引数のint型としてのintので、[]パラメータのタイプ。

したがって、一般的な完了の上記の方法は次のようになります。

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)のArrayList内の要素のリストを参照しない独立したオブジェクトで返さ

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]

我々は、配列の元の内容も変更され、コレクションの内容を変更するために見えるので、ここで渡された参照型です。

(4)の既知の配列データ、どのように迅速にリストをチェックするために追加および削除のリストを取得するには?

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()メソッドシーン

アレイユーティリティクラスがメソッドasListを提供し、パラメータまたは変数の長さの配列を使用することができる方法は、リストを変換しました。しかし、得られた長さは固定リストであり、動作は、(例えば、要素の位置を変えること)変更することができ、長さ(例えば、他の動作を削除、追加)を行う、又はUnsupportedOperationExceptionがスローすることができません。

だから、は、Arrays.asListすでにデータの配列を持っている人、または迅速なシーンの操作を追加または削除せず、唯一の読み取り操作のために、リストを構築するために必要な要素のうちのいくつかのために、より適しています。

2、ソート

このメソッドは、ソートすることができ、配列をソートするために使用される一連の処理が過負荷になっているクラス・アレイ内のメソッドは、バイトなどの基本データ型、char型、ダブル、フロート、int型、長い、短い、などの7種類のことができタイプ(Comparableインタフェースを実装する)、及びコンパレータコンパレータがオブジェクト。

(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]

(2)オブジェクトタイプのアレイを

配列のこのタイプのソートcompareToメソッドをオーバーライドし、同等のインターフェースソートを実現することができます。

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

文字列型が同等のインタフェースを実装し、内部compareToメソッドは、辞書符号に応じて比較されます。

Comparableインタフェースを実装していない、コンパレータの並べ替えを介して達成することができます

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

二分法で配列の要素を検索します。さまざまなオブジェクトと基本データ型に適用可能な方法と同一のソート方法。

注:二分法である規則正しい配列を見つけるために(例えば)は、Arrays.sort(と第一種として、次に見つけるために、このメソッドを呼び出します)。見つかった添字の要素戻り、なしまたは-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

特定のソースコードの実装:

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とcopyOfRange

(1)copyOf

コピー配列要素。だから、コピーは、指定された長さを有しています。使用底System.arraycopyの()ネイティブメソッドである、実施。

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

たとえば、

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

おすすめ

転載: www.cnblogs.com/xzh0717/p/11297566.html