Skip to content

Arrays

About 1526 wordsAbout 5 min

2025-05-06

Arrays类是在java.util包里面。

一、Arrays源码学习

Arrays中主要涉及的方法有:

  • sort
  • binarySearch
  • fill
  • copyOf
  • copyOfRange
  • asList

static String toString(Object[] a)

Arrays.toString 方法就是方便讲数组转成字符串,使用中括号包裹,通过StringBuilder来实现,循环在后面添加元素,最后通过StringBuilder.toString 返回字符串

static void sort(int[] a)

Arrays类中提供的排序方法,在原始数组上面进行修改。

// 可以对int[], long[], char[], short[], byte[], float[], double[]等基础类型数组进行排序 
public static void sort(int[] a);
public static void sort(int[] a, int fromIndex, int toIndex);

如果需要倒序排序的话,可以传入一个比较器。

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else if (Arrays.LegacyMergeSort.userRequested) {
        legacyMergeSort(a, c);
    } else {
        TimSort.sort(a, 0, a.length, c, (Object[])null, 0, 0);
    }

}

逆序排序举例:

要对对象数组进行排序的话,对象类必须实现Comparable接口,并实现compareTo方法.

public class TreeNode implements Comparable<TreeNode> {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val) {
        this.val = val;
    }
    @Override
    public int compareTo(TreeNode treeNode) {
        return this.val - treeNode.val;
    }
}
TreeNode[] nodes = new TreeNode[3];
nodes[0] = new TreeNode(3);
nodes[1] = new TreeNode(2);
nodes[2] = new TreeNode(1);
Arrays.sort(nodes);
System.out.println(Arrays.toString(nodes));

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)

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

比如下面例子;

Integer[] arr2 = new Integer[] {1, 2, 34};
Arrays.sort(arr2, (a, b) -> b - a);
Arrays.sort(arr2, (a, b) -> {
    return b - a;
});
Arrays.sort(arr2, Collections.reverseOrder());

static int binarySearch(long[] a, long key)

最常用的二分查找,需要保持原数组有序。

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

类似方法:

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

public static void fill(int[] a, int val) {
    for (int i = 0, len = a.length; i < len; i++)
      	// 全部填充为val
        a[i] = val;
}

static int[] copyOf(int[] original, int newLength)

复制数组,original表示原来数组,newLength表示新数组的长度。

public static int[] copyOf(int[] original, int newLength) {
  	// 创建一个长为newLength的新数组
    int[] copy = new int[newLength];
  	// 通过底层System.arraycopy方法将元素拷贝到新数组里面。
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    return copy;
}

补充内容:

    int[] arr = new int[]{3, 2, 4, 1, 5};
    int[] arr2 = new int[10];
    // srcPos + length 
    System.arraycopy(arr, 0, arr2, 1, 3);

    // [from, to)
    int[] ints = Arrays.copyOfRange(arr, 1, 2);

    for (int x : arr2) {
        System.out.println(x);
    }

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

顾名思义。

public static int[] copyOfRange(int[] original, int from, int to) {
  	// to - from表示数组长度
    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;
}

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

T... a底层转化为T[] x的数组。

public static <T> List<T> asList(T... a) {
  	// 这里的ArrayList不是java.util里面的类,是Arrays类中的内部类
    return new ArrayList<>(a);
}

static String toString(int[] a)

通过StringBuilder 循环拼接数组元素。

static InStream stream(int[] array)

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

static void fill(Object[] a, Object val)

使用val填充数组a。

感觉有点像变异的while循环。

public static void fill(Object[] a, Object val) {
    int i = 0;
    for(int len = a.length; i < len; ++i) {
        a[i] = val;
    }
}

它这个fill方法为什么要这么写for循环呢?和我们常规思路写出来的循环应该没有什么区别吧?

int len = a.length;
for(int i = 0;i<len;++i){
  ...
}

举例说明:

定义一个数组,然后把数组的每一个值都设置成10

int[] arr = new int[10];
Arrays.fill(arr, 10);

static <T> void setAll(T[] array, IntFunction<? Extends T> generator)

使用提供的生成器函数设置指定数组的所有元素以计算每个元素

public static <T> void setAll(T[] array, IntFunction<? extends T> generator) {
    Objects.requireNonNull(generator);
    for(int i = 0; i < array.length; ++i) {
        array[i] = generator.apply(i);
    }
}

举例说明,下面的g是一个列表数组,然后使用setAll方法,将每一个元素都默认设置成一个数组。

List<Integer>[] g = new ArrayList[10];
Arrays.setAll(g, x -> new ArrayList<>());

二、Arrays内部类ArrayList

Changelog

8/20/25, 11:06 AM
View All Changelog
  • 4c155-Merge branch 'dev1'on

求求了,快滚去学习!!!

求求了求求了,快去学习吧!

【题单】贪心算法

不知道方向的时候,可以多看看书,书会给你指明下一步该干什么,加油!