# Arrays

`java.util.Arrays`是Java提供的针对数组的工具类。

## 方法

Arrays主要分为以下几种类型的方法：

1. 将数组转换为List
2. 二分法查找元素在数组中的索引
3. 拷贝数组
4. 比较数组
5. 数组排序
6. 填充数组
7. 根据数组生成hashCode
8. 将数组转换为字符串

### 数组->List

```java
static <T> List<T> asList(T... a)
```

返回一个受指定数组支持的**固定大小**的列表。

#### 示例

执行代码：

```java
List<String> strings = Arrays.asList("a", "b", "c");
strings.add("c");
System.out.println(strings);
```

结果:

```
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:131)
    at java.util.AbstractList.add(AbstractList.java:91)
    at spring.test.Test.main(Test.java:38)
```

这是因为，asList返回的实例的类型不是`java.util.ArrayList`，而是Arrays的内部类`ArrayList`，这个类同样继承`AbstractList`，但是此类被设计为固定大小的List，没有实现add等方法。

源码如下：

```java
public static <T> List<T> asList(T... a) {
    // 直接使用a数组作为ArrayList的源，所以a数组变化，list也会变化
    return new ArrayList<T>(a);
}

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) {
        if (array==null)
            throw new NullPointerException();
        a = array;
    }

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

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

    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;
    }

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

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

    public int indexOf(Object o) {
        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;
    }
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }
}
```

### 数组拷贝

`System.arrayCopy`本地方法已经可以完成数组的拷贝，但是传入的类型为Object\[],得到的类型Object\[] 有可能造成类型转换异常等问题，而且传入参数过多，不便使用。所以，在Arrays中又提供了`Arrays.copyOf`和`Arrays.copyOfRange`方法，更方便完成数组操作。

基本类型：

* `static boolean[] copyOf(boolean[] original, int newLength)`
* `static byte[] copyOf(byte[] original, int newLength)`
* `static char[] copyOf(char[] original, int newLength)`
* `static short[] copyOf(short[] original, int newLength)`
* `static int[] copyOf(int[] original, int newLength)`
* `static long[] copyOf(long[] original, int newLength)`
* `static float[] copyOf(float[] original, int newLength)`
* `static double[] copyOf(double[] original, int newLength)`
* `static boolean[] copyOfRange(boolean[] original, int from, int to)`
* `static byte[] copyOfRange(byte[] original, int from, int to)`
* `static char[] copyOfRange(char[] original, int from, int to)`
* `static short[] copyOfRange(short[] original, int from, int to)`
* `static int[] copyOfRange(int[] original, int from, int to)`
* `static long[] copyOfRange(long[] original, int from, int to)`
* `static float[] copyOfRange(float[] original, int from, int to)`
* `static double[] copyOfRange(double[] original, int from, int to)`

泛型，用于copy对象类型，空余使用null填充：

* `static <T> T[] copyOf(T[] original, int newLength)`
* `static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType)`
* `static <T> T[] copyOfRange(T[] original, int from, int to)`
* `static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType)`

注意： Arrays.copyOf底层就是调用System.copyOf。
