【Java 专题补充】Arrays类详解

目录

一、关于动态创建

二、Arrays 类简介

三、Arrays 类常用函数介绍

1. Arrays.toString(array)

2. Arrays.copyOf(array, length)

3. Arrays.sort(array)

4. Arrays.binarySearch(array, Constant) 

5. Arrays.fill(array, Constant) 

 6. Arrays.equals(array1, array2)

 7. Arrays.deepEquals(matrix1, matrix2)

8. Arrays.deepToString(matrix)

9. Arrays.asList(array) 

10. else


一、关于动态创建

         需要注意的是,java中的数组声明方案实际上是有两个的,传统的方法是:

dataType arrayRefVar[];

        这个方法继承了C与C++的衣钵,Java源文档中也特别说明此方案是为方便原C与C++程序员能尽快适应java语言。但是这种方案并不常用,很不“java”。
        现在更常用的数组声明方案是:

dataType[] arrayRefVar;

        这个方案很像C#,但是其实历史上C#是微软与SUN公司(出品java的公式)闹掰之后自己仿造java创立的语言,所以也许说C#的数组声明的来源正是来自这也说不定。
        声明完毕后需要为数组动态分配空间,其中动态分配方法来源于C++的new方法:

dataType[] arrayRefVar = new dataType[arraySize];

        这个语句做了什么呢?

  1. 使用dataType[arraySize]创建了一个数组
  2. 把创建的数组的引用赋值给变量 arrayRefVar

        那么,如果要创建多维数组呢?只需要修改数据类型即可:

dataType[][] arrayRefVar = new dataType[arrayHeight][arrayWidth];

        插一句静态创建
        最后提一句,动态创建不是唯一的创建方案,数组的静态创建也是常用的,其风格与C语言系列类似,可通过在[ ]写入确定量或者用{ }取等预定元素都是可以的:

dataType[10] arrayRefVar1;
dataType[10][20] arrayRefVar1;
double[] arrayRefVar2 = {1.2, 2.3, 3.4};

二、Arrays 类简介

        Arrays 类是 Java 语言中用于操作数组的一个工具类,提供了多种静态方法来处理数组,包括排序、搜索、填充、比较等操作。这个类位于 java.util 包中。

        Arrays类的构造方法被设置为私有(private),因此无法创建 Arrays 对象。Arrays 类的所有公有方法都是静态的,可以直接通过类名调用。

三、Arrays 类常用函数介绍

1. Arrays.toString(array)

        返回一维数组的字符串表示。

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[] arr = {1, 2, 3, 4, 5, 6};
		System.out.println(Arrays.toString(arr));
	}
}

 

(2)源码 

    public static String toString(int[] a) {
        if (a == null) // 判断 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(", ");
        }
    }

         本质上是对数组进行遍历。

2. Arrays.copyOf(array, length)

        复制数组,可以指定新数组长度。 

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		// 原始数组
		int[] originalArray = {1, 2, 3, 4, 5};
 
		// 复制数组,指定新数组的长度
		// 新数组长度小于原数组长度
		int[] newArray1 = Arrays.copyOf(originalArray, 3);
		System.out.println("新数组1: " + Arrays.toString(newArray1)); // 输出: [1, 2, 3]
 
		// 新数组长度大于原数组长度
		int[] newArray2 = Arrays.copyOf(originalArray, 8);
		System.out.println("新数组2: " + Arrays.toString(newArray2)); // 输出: [1, 2, 3, 4, 5, 0, 0, 0]
 
		// 新数组长度等于原数组长度
		int[] newArray3 = Arrays.copyOf(originalArray, originalArray.length);
		System.out.println("新数组3: " + Arrays.toString(newArray3)); // 输出: [1, 2, 3, 4, 5]
	}
}

        也就是说第一个参数是源数组,第二个参数是从源数组中复制多少个元素到新数组中,如果第二个参数大于了源数组的大小,则新数组中大于源数组大小的部分的元素都是类型默认值。 

(2)存疑

        具体涉及的深拷贝,浅拷贝问题不在这里解答。从原理上讲与 C++ 涉及的是相同的,感兴趣可以自行前往 

3. Arrays.sort(array)

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[] arr = {11, 33, 99, 22, 88, 44, 55, 66, 77};
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));
	}
}

         可以发现这里的顺序是升序排列,那如何实现降序排列呢,就要用到下面这种方式了。

(2)带 Comparator 接口的 sort() 方法的使用

import java.util.Arrays;
import java.util.Comparator;
 
public class Example {
	public static void main(String[] args) {
		Integer[] arr = {11, 33, 99, 22, 88, 44, 55, 66, 77};
        // 这里要使用 Integer 包装类        
 
		Arrays.sort(arr, new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2 - o1;
			}
		});
		System.out.println(Arrays.toString(arr));
	}
}

         这里的数组不能使用基本数据类型,因为这里的 sort() 方法的声明是这样的:

public static <T> void sort(T[] a, Comparator<? super T> c);

         这里的 sort 是一个泛型方法,泛型参数只能接受类类型,所以这里需要使用包装类型数组作为第一个参数,对于第二个参数,我们传入的是:

    new Comparator<Integer>() {
		@Override
		public int compare(Integer o1, Integer o2) {
			return o2 - o1;
		}
	}

        这显然是一个匿名内部类,它实现了 Comparator 接口,同时重写了这个接口的 compare() 方法,这个方法是关键,这里返回值是 o2 - o1,这就代表了,如果 o1 如果大于 o2 的话,则返回负值,对于 sort() 方法内部某个地方就是调用的 compare() 方法来比较两个参数的大小。

        如果是升序的话,o1 大于 o2 应当返回的是正值,这里返回了负值,所以就是将顺序设置为反的,所以最终可以得到降序的数组。

(3) 相关算法

  • 基本类型数组(如 int[], char[] 等):

        对于基本数据类型数组,Arrays.sort() 方法使用了一种名为 Dual-Pivot Quicksort 的排序算法。这是一种改进的快速排序算法,由 Vladimir Yaroslavskiy 提出。它在平均情况下具有 O(n log n) 的时间复杂度,并且在实践中通常表现良好。
 

  • 对象类型数组(如 Integer[], String[] 等):

        对于对象数组,Arrays.sort() 方法则使用 Timsort 算法。这是一种混合排序算法,结合了归并排序和插入排序的优点。Timsort 是为了优化对部分有序数据的排序而设计的,具有 O(n log n) 的时间复杂度,并且在实际应用中表现出色。

4. Arrays.binarySearch(array, Constant) 

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[] arr = {11, 22, 33, 44, 55, 66, 77, 88, 99};
 
		// Arrays.sort(arr)
		// 在调用 binarySearch 前需要对数组先进行排序
		// 这里为了方便比对结果,数组已经是有序的
		int index = Arrays.binarySearch(arr, 99);
 
		System.out.println("index of 99: " + index);
	}
}

 (2)源码 
        binarySearch() 方法内部会调用 binarySearch0() 方法:

    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); // 没有找到不是直接返回负一,返回一个特定的负数
    }

5. Arrays.fill(array, Constant) 

        用指定的值填充数组,如果想要将一个数组的所有元素都是设置为某个值的话,可以使用这个方法。

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[] arr = new int[10];
		Arrays.fill(arr, 2333);
 
		System.out.println(Arrays.toString(arr));
	}
}

 6. Arrays.equals(array1, array2)

        Arrays.equals() 方法用于比较两个一维数组是否相等。

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[] array1 = {1, 2, 3};
		int[] array2 = {1, 2, 3};
		int[] array3 = {1, 2, 4};
 
		// 比较相同的数组
		boolean isEqual1 = Arrays.equals(array1, array2);
		System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true
 
		// 比较不同的数组
		boolean isEqual2 = Arrays.equals(array1, array3);
		System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false
	}
}

 7. Arrays.deepEquals(matrix1, matrix2)

        Arrays.deepEquals() 方法用于比较两个多维数组是否相等。它会递归地比较数组的每个元素。如果使用 Arrays.equals() 方法的话,则只会比较每一个低一维数组的引用是否相等。

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[][] array1 = {{1, 2, 3}, {4, 5, 6}};
		int[][] array2 = {{1, 2, 3}, {4, 5, 6}};
		int[][] array3 = {{1, 2, 3}, {4, 5, 7}};
 
		// 比较相同的二维数组
		boolean isEqual1 = Arrays.deepEquals(array1, array2);
		System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true
 
		// 比较不同的二维数组
		boolean isEqual2 = Arrays.deepEquals(array1, array3);
		System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false
	}
}

(2)对比 Arrays.equals()

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[][] array1 = {{1, 2, 3}, {4, 5, 6}};
		int[][] array2 = {{1, 2, 3}, {4, 5, 6}};
		int[][] array3 = {{1, 2, 3}, {4, 5, 7}};
 
		// 比较相同的二维数组
		boolean isEqual1 = Arrays.equals(array1, array2); // 使用 equals()
		System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true
 
		// 比较不同的二维数组
		boolean isEqual2 = Arrays.equals(array1, array3); // 使用 equals()
		System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false
	}
}

8. Arrays.deepToString(matrix)

        Arrays.deepToString() 方法用于返回多维数组的字符串表示。如果使用 Arrays.toString() 方法则会返回低一维数组的引用值的数组。

(1)示例(代码及运行结果)

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[][] array = {{1, 2, 3}, {4, 5, 6}};
 
		// 获取并打印数组的字符串表示
		String arrayString = Arrays.deepToString(array);
		System.out.println("数组的字符串表示: " + arrayString); // 输出: [[1, 2, 3], [4, 5, 6]]
	}
}

(2)对比 Arrays.toString() 方法

import java.util.Arrays;
 
public class Example {
	public static void main(String[] args) {
		int[][] array = {{1, 2, 3}, {4, 5, 6}};
 
		// 获取并打印数组的字符串表示
		String arrayString = Arrays.toString(array); // 使用 toString()
		System.out.println("数组的字符串表示: " + arrayString); // 输出: [[1, 2, 3], [4, 5, 6]]
	}
}

9. Arrays.asList(array) 

        将数组转换为 List:

(1)示例(代码及运行结果)

import java.util.Arrays;
import java.util.List;
 
public class Example {
	public static void main(String[] args) {
		String[] fruitsArray = {"Apple", "Banana", "Cherry"};
 
		// 使用 Arrays.asList 将数组转为列表
		List<String> fruitsList = Arrays.asList(fruitsArray);
 
		// 打印列表
		System.out.println("水果列表: " + fruitsList); // 输出: 水果列表: [Apple, Banana, Cherry]
	}
}

        修改列表的元素,数组的元素也会变化:

import java.util.Arrays;
import java.util.List;
 
public class Example {
	public static void main(String[] args) {
		Integer[] numbersArray = {1, 2, 3, 4, 5};
 
		// 转换为列表
		List<Integer> numbersList = Arrays.asList(numbersArray);
 
		// 修改列表中的元素
		numbersList.set(0, 10);
 
		// 打印修改后的列表和数组
		System.out.println("修改后的列表: " + numbersList); // 输出: 修改后的列表: [10, 2, 3, 4, 5]
		System.out.println("修改后的数组: " + Arrays.toString(numbersArray)); // 输出: 修改后的数组: [10, 2, 3, 4, 5]
	}
}

(2)不能使用添加元素

import java.util.Arrays;
import java.util.List;
 
public class Example {
	public static void main(String[] args) {
		String[] colorsArray = {"Red", "Green", "Blue"};
 
		// 转换为列表
		List<String> colorsList = Arrays.asList(colorsArray);
 
		// 尝试添加新元素(会抛出 UnsupportedOperationException)
		try {
			colorsList.add("Yellow");
		} catch (UnsupportedOperationException e) {
			System.out.println("无法添加元素到列表: " + e.getMessage());
		}
	}
}

        这是因为我们使用 Arrays.asList() 方法将数组转换为 List 时,返回的列表是一个基于原始数组的固定大小的视图。这意味着:

固定大小:返回的 List 的大小是固定的,因为原数组的大小是固定的。换句话说,您不能向该列表中添加或删除元素,因为这会导致列表的大小发生变化。当尝试调用 add() 或 remove() 方法来修改列表的大小时,会抛出 UnsupportedOperationException。因为 Arrays.asList() 返回的列表并不支持这些操作。

10. else

        这里给出一张图片,详细需要请参考具体的库函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值