Arrays工具类


一、什么是Arrays类

  Arrays 类是一个工具类,其中包含了数组操作的很多方法。这个 Arrays 类里均为 static 修饰的方法(static 修饰的方法可以直接通过类名调用),可以直接通过 Arrays.xxx(xxx) 的形式调用方法。

二、静态方法

 1)int binarySearch(type[] a, type key)

  使用二分法查询 key 元素值在 a 数组中出现的索引,如果 a 数组不包含 key 元素值,则返回负数。调用该方法时要求数组中元素己经按升序排列,这样才能得到正确结果。

 2)int binarySearch(type[] a, int fromIndex, int toIndex, type key)

  这个方法与前一个方法类似,但它只搜索 a 数组中 fromIndex 到 toIndex 索引的元素。调用该方法时要求数组中元素己经按升序排列,这样才能得到正确结果。

 3)type[] copyOf(type[] original, int length)

  这个方法将会把 original 数组复制成一个新数组,其中 length 是新数组的长度。如果 length 小于 original 数组的长度,则新数组就是原数组的前面 length 个元素,如果 length 大于 original 数组的长度,则新数组的前面元索就是原数组的所有元素,后面补充 0(数值类型)、false(布尔类型)或者 null(引用类型)。

 4)type[] copyOfRange(type[] original, int from, int to)

  这个方法与前面方法相似,但这个方法只复制 original 数组的 from 索引到 to 索引的元素。

 5)boolean equals(type[] a, type[] a2)

  如果 a 数组和 a2 数组的长度相等,而且 a 数组和 a2 数组的数组元素也一一相同,该方法将返回 true。

 6)void fill(type[] a, type val)

  该方法将会把 a 数组的所有元素都赋值为 val。

 7)void fill(type[] a, int fromIndex, int toIndex, type val)

  该方法与前一个方法的作用相同,区别只是该方法仅仅将 a 数组的 fromIndex 到 toIndex 索引的数组元素赋值为 val。

 8)void sort(type[] a)

  该方法对 a 数组的数组元素进行排序。

 9)void sort(type[] a, int fromIndex, int toIndex)

  该方法与前一个方法相似,区别是该方法仅仅对 fromIndex 到 toIndex 索引的元素进行排序。

 10)String toString(type[] a)

  该方法将一个数组转换成一个字符串。该方法按顺序把多个数组元素连缀在一起,多个数组元素使用英文逗号,和空格隔开。

在JAVA8之后增强了Arrays的功能,新增的方法可以充分利用多 CPU 并行的能力来提高设值、排序的性能。

  提示:由于计算机硬件的飞速发展,目前几乎所有家用 PC 都是 4 核、8 核的 CPU,而服务器的 CPU 则具有更好的性能,因此 Java 8 与时俱进地增加了并发支持,并发支持可以充分利用硬件设备来提高程序的运行性能。

 1)oid parallelPrefix(xxx[] array, XxxBinaryOperator op)

  该方法使用 op 参数指定的计算公式计算得到的结果作为新的元素。op 计算公式包括 left、right 两个形参,其中 left 代表数组中前一个索引处的元素,right 代表数组中当前索引处的元素,当计算第一个新数组元素时,left 的值默认为 1。

 2)void parallelPrefix(xxx[] array, int fromIndex, int toIndex, XxxBinaryOperator op)

  该方法与上一个方法相似,区别是该方法仅重新计算 fromIndex 到 toIndex 索引的元素。

 3)void setAll(xxx[] array, IntToXxxFunction generator)

  该方法使用指定的生成器(generator)为所有数组元素设置值,该生成器控制数组元素的值的生成算法。

 4)void parallelSetAll(xxx[] array, IntToXxxFunction generator)

  该方法的功能与上一个方法相同,只是该方法增加了并行能力,可以利用多 CPU 并行来提高性能。

 5)void parallelSort(xxx[] a)

  该方法的功能与 Arrays 类以前就有的 sort() 方法相似,只是该方法增加了并行能力,可以利用多 CPU 并行来提高性能。

 6)void parallelSort(xxx[] a,int fromIndex, int toIndex)

  该方法与上一个方法相似,区別是该方法仅对 fromIndex 到 toIndex 索引的元素进行排序。

 7)Spliterator.OfXxx spliterator(xxx[] array)

  将该数组的所有元素转换成对应的 Spliterator 对象。

 8)Spliterator.OfXxx spliterator(xxx[] array, int startInclusive, int endExclusive)

  该方法与上一个方法相似,区别是该方法仅转换 startInclusive 到 endExclusive 索引的元素。

 9)XxxStream stream(xxx[] array)

  该方法将数组转换为 Stream,Stream 是 Java 8 新增的流式编程的 API。

 10)XxxStream stream(xxx[] array, int startInclusive, int endExclusive)

  该方法与上一个方法相似,区别是该方法仅将 fromIndex 到 toIndex 索引的元索转换为 Stream。

  上面方法列表中,所有以 parallel 开头的方法都表示该方法可利用 CPU 并行的能力来提高性能。上面方法中的 xxx 代表不同的数据类型,比如处理 int[] 型数组时应将 xxx 换成 int,处理 long[] 型数组时应将 XXX 换成 long。

三、常用方法

  •         * public static String toString(数组)
  •         * public static int binarySearch(数组,查找的长度)
  •         * public static int[] copyOf(原数组,新数组长度)
  •         * public static int[] copyOfRange(原数组,起始索引,结束索引)
  •         * public static void fill(数组,元素)
  •         * public static void sort(数组)
  •         * public static void sort(数组,排序规则)

1.toString():

  可以将数组变成字符串,包含数组中的每一个元素,以[]包裹

        System.out.println("---------------toString----------------");
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        System.out.println(Arrays.toString(arr));

2.binarySearch():

  使用二分查找来获取第一个指定元素的索引

        System.out.println("-------------binarySearch--------------");
        System.out.println(Arrays.binarySearch(arr,10));
        System.out.println(Arrays.binarySearch(arr,2));
        System.out.println(Arrays.binarySearch(arr,20));

!注意点!:

  1.被查找的数组必须是有序的     2.当元素不存在时,返回值为“负的插入点位置减一

3.copyOf();

  对原有数组进行拷贝,返回一个新的数组(地址值也与原先数组不同)

        System.out.println("----------------copyOf-----------------");
        int[] newArr = Arrays.copyOf(arr,20);
        System.out.println(Arrays.toString(newArr));

4.copyOfRange()

  与copyOf方法类似,可以指定拷贝的索引范围,方法也返回一个新的数组地址

        System.out.println("--------------copyOfRange--------------");
        int[] newArr2 = Arrays.copyOfRange(arr,0,9);
        System.out.println(Arrays.toString(newArr2));

5.fill()

  将数字以指定的元素填充

        System.out.println("------------------fill-----------------");
        int[] newArr3 = new int[10];
        Arrays.fill(newArr3,100);
        System.out.println(Arrays.toString(newArr3));

6.sort();

  ①.默认为升序排序,传入数组

        System.out.println("------------------sort-----------------");
        int[] arr2 = {10,2,3,5,6,1,7,8,4,9};
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));

  ②.当需要指定排序规则时,需要传入Comparator接口的实现类

        Integer[] arr3 = {2,3,1,5,6,7,8,4,9};
        Arrays.sort(arr3, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println("----------");
                System.out.println("o1: " + o1);
                System.out.println("o2: " + o2);
                return o1-o2;
            }
        });
        System.out.println(Arrays.toString(arr3));
  Comparator接口的底层原理:先通过二分查找,在有序区中找到指定位置的索引,再通过插入排序将元素插入有序区

   这里的o1o2分别是找到索引处的对象和需要存入数组的对象,函数的返回值有以下作用:
   负数:表示当前要插入的元素的小的,放在前面
   正数:表示当前要插入的元素的大的,放在后面
   0:表示当前要插入的元素跟现在的元素比较是一样的,也会放在后面
   
  在上面的代码中,使用了匿名内部类的方式传递接口的实现类对象,但这样的方法比较繁琐,所以我们可以使用Lambda表达式来简化书写。
  

        Integer[] arr3 = {2,3,1,5,6,7,8,4,9};
        Arrays.sort(arr3,(o1,o2)->o1-o2);
        System.out.println(Arrays.toString(arr3));