一、概述
Arrays类是Java标准库中的一个工具类,位于java.util包中,专门为操作数组提供了一组静态方法(例如排序、搜索、填充、比较、转换等)。
二、常用方法
1、转换字符串方法:将数组转换为字符串表示。分为一维数组和多为数组两种形式:
- 1)、String toString(Object[] a):将一维数组转换为字符串表示。
- 2)、String deepToString(Object[] a):将多维数组转换为字符串表示。
public class ArraysTest {
public static void main(String[] args) {
// 1、字符串转换方法
// 1)、Arrays.toString(array):将数组转换为字符串表示。
int[] arrays = {11, 44, 77, 33, 66};
System.out.println(Arrays.toString(arrays)); // 输出 [11, 44, 77, 33, 66]
// 2、Arrays.deepToString(Object[] a):将多维数组转换为字符串表示。
int[][] array = {{1, 2}, {3, 4}};
System.out.println(Arrays.toString(array)); // 输出 [[I@6e8dacdf, [I@7a79be86]
System.out.println(Arrays.deepToString(array)); // 输出 [[1, 2], [3, 4]]
}
}
2、排序方法sort():用于对数组进行排序(默认升序)。可以对 int、double、char 等基本类型数组进行排序,也可以对对象数组进行排序。
- 1)、Arrays.sort(array):对数组进行升序排序(适用于基本类型和对象类型)。如果是对象数组则对应的类必须实现 Comparable 接口。
- 2)、Arrays.sort(array, Comparator):按照指定的比较器对对象数组进行排序(适用于对象数组)。
public class ArraysTest {
public static void main(String[] args) {
// 1)、Arrays.sort(array):对数组进行升序排序。
int[] arrays = {11, 44, 77, 33, 66};
Arrays.sort(arrays);
System.out.println(Arrays.toString(arrays)); // 输出 [11, 33, 44, 66, 77]
// 2)、Arrays.sort(array, Comparator):按照指定的比较器对对象数组进行排序。
Person[] personArray = {
new Person("张三", 22),
new Person("李四", 33),
new Person("王五", 18)
};
// 按照年龄进行排序
Arrays.sort(personArray, (Comparator.comparingInt(Person::getAge)));
System.out.println(Arrays.toString(personArray)); // 输出 [Person{name='王五', age=18}, Person{name='张三', age=22}, Person{name='李四', age=33}]
}
}
3、查找方法binarySearch():使用二分查找法在“已排序”的数组中查找指定元素的索引。
- 1)、int binarySearch(int[] a, int key):使用二分查找法在已排序的整型数组中查找指定值,返回索引。
public class ArraysTest { public static void main(String[] args) { int[] array = {11, 44, 77, 33, 66}; System.out.println(Arrays.binarySearch(array, 33)); // 输出-2,数组未先排序 Arrays.sort(array); // 使用binarySearch()方法必须先对数组进行排序 System.out.println(Arrays.binarySearch(array, 33)); // 输出1 System.out.println(Arrays.binarySearch(array, 44)); // 输出2 } }
- 2)、int binarySearch(Object[] a, Object key):使用二分查找法在已排序的对象数组中查找指定对象,返回索引。对象必须要实现Comparable 接口,重写compareTo()方法对对象进行自然排序,否则会报异常ClassCastException。
public class ArraysTest { public static void main(String[] args) { // 必须要实现Comparable 接口,重写compareTo()方法对对象进行自然排序。 Student s1 = new Student("张三", 22); Student s2 = new Student("李四", 33); Student s3 = new Student("王五", 18); Student[] students = {s1, s2, s3}; Arrays.sort(students); System.out.println(Arrays.binarySearch(students, s1)); // 输出 1 System.out.println(Arrays.binarySearch(students, s2)); // 输出 2 } } public class Student implements Comparable<Student> { private String name; private Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } @Override public int compareTo(Student other) { // 根据年龄进行自然排序 return this.age.compareTo(other.getAge()); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
- 3)、int binarySearch(T[] a, T key, Comparator<? super T> c):使用指定的比较器在已排序的对象数组中查找指定对象,返回索引。比较器仅用于在搜索过程中指定根据对象的哪个属性进行查找,并不是让数组根据提供的比较器进行排序。
public class ArraysTest { public static void main(String[] args) { Person p1 = new Person("张三", 22); Person p2 = new Person("李四", 33); Person p3 = new Person("王五", 18); Person[] personArray = {p1, p2, p3}; // 先根据年龄字段进行排序,然后再进行查找 Arrays.sort(personArray, Comparator.comparingInt(Person::getAge)); System.out.println(Arrays.binarySearch(personArray, p1,Comparator.comparing(Person::getAge))); // 输出 1 System.out.println(Arrays.binarySearch(personArray, p2,Comparator.comparing(Person::getAge))); // 输出2 } } // 传入比较器的方式Person无需实现Comparable自然排序接口 public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name) && Objects.equals(age, person.age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
4、比较方法equals():用于比较两个数组是否相等的方法(两个数组必须是相同类型)。该方法会逐一比较这两个数组中的元素,如果所有元素都相等(包括数组的类型、长度和每个位置的元素值),则返回 true,否则返回 false。
- 1)、boolean equals(int[] a, int[] a2) :基本数据类型数组的比较,返回一个boolean。
- 2)、boolean equals(Object[] a, Object[] a2):对象数组的比较,返回一个boolean。如果是自定义对象,则需要重写equalls()方法,否则使用的是Object类的equals()方法比较的是对象的地址。
- 3)、boolean deepEquals(Object[] a1, Object[] a2):多维数组的比较,返回一个boolean值。
public class ArraysTest {
public static void main(String[] args) {
// 1)、基本数据类型数组的比较
int[] array1 = {33, 55, 77, 99};
int[] array2 = {22, 44, 66, 88};
int[] array3 = {33, 55, 77, 99};
System.out.println(Arrays.equals(array1, array2)); // 输出false
System.out.println(Arrays.equals(array1, array3)); // 输出true
System.out.println(Arrays.equals(array2, array3)); // 输出false
// 2)、对象数组的比较
Person[] array4 = {
new Person("张三", 22),
new Person("李四", 33),
new Person("王五", 18)
};
Person[] array5 = {
new Person("张三", 22),
new Person("王五", 18),
new Person("李四", 33)
};
Person[] array6 = {
new Person("张三", 22),
new Person("李四", 33),
new Person("王五", 18)
};
System.out.println(Arrays.equals(array4, array5)); // 输出false
System.out.println(Arrays.equals(array4, array6)); // 输出true
System.out.println(Arrays.equals(array5, array6)); // 输出false
// 3)多维数组的比较
int[][] array7 = {{1, 2}, {3, 4}};
int[][] array8 = {{1, 2}, {3, 4}};
int[][] array9 = {{1, 2}, {3, 5}};
System.out.println(Arrays.deepEquals(array7, array8)); // 输出 true
System.out.println(Arrays.deepEquals(array7, array9)); // 输出 false
}
}
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
5、填充方法fill():用于快速填充数组的元素。无论是基本类型数组还是引用类型数组,都可以使用这个方法来简化代码。在实际应用中,它有助于初始化、重置和填充默认值。
- 1)、void fill(int[] a, int val):将指定值填充到数组的所有元素中(即将数组中所有的元素都赋值为指定值)。
- 2)、void fill(int[] a, int fromIndex, int toIndex, int val):将指定值填充到数组的指定范围内 [fromIndex, toIndex)的元素中。
- 3)、void setAll(int[] array, IntUnaryOperator generator):使用生成器填充数组中的所有元素。
public class ArraysTest {
public static void main(String[] args) {
// 5、填充方法
// 1)、fill(int[] a, int val):将指定值填充到数组的所有元素中
int[] numbers = new int[5];
Arrays.fill(numbers, 10);
System.out.println("将数组中所有的元素值填充为10:");
System.out.println(Arrays.toString(numbers)); // 输出[10, 10, 10, 10, 10]
Person[] people = new Person[5];
Arrays.fill(people, new Person("张三", 22));
System.out.println("将数组中所有的元素值填充为张三:");
System.out.println(Arrays.toString(people)); // 输出[Person{name='张三', age=22}, Person{name='张三', age=22}, Person{name='张三', age=22}, Person{name='张三', age=22}, Person{name='张三', age=22}]
// 2)、将指定值填充到数组的指定范围内
int[] numbers2 = new int[10];
Arrays.fill(numbers2, 1, 4, 5);
System.out.println("将数组索引为1,2,3的元素值填充为5");
System.out.println(Arrays.toString(numbers2)); // 输出[0, 5, 5, 5, 0, 0, 0, 0, 0, 0]
Person[] people2 = new Person[10];
Arrays.fill(people2, 1, 4, new Person("李四", 22));
System.out.println("将数组索引为1,2,3的元素值填充为李四:");
System.out.println(Arrays.toString(people2)); // 输出[null, Person{name='李四', age=22}, Person{name='李四', age=22}, Person{name='李四', age=22}, null, null, null, null, null, null]
// 3)、setAll(int[] array, IntUnaryOperator generator):使用生成器填充数组中的所有元素。
int[] numbers3 = new int[5];
Arrays.setAll(numbers3, x -> ThreadLocalRandom.current().nextInt(100));
System.out.println("使用生成器填充1-100的随机数到数组中:");
System.out.println(Arrays.toString(numbers3)); // 输出随机数组[16, 69, 39, 4, 35]
}
}
6、数组转换方法:主要为数组转换为List和Stream,转换为String前面已提到。
- 1)、List<T> asList(T... a):将数组转换为List集合。有以下弊端:
- Ⅰ、不能直接转换基本类型数组:Arrays.asList()方法参数是一个对象数组。当传入基本类型数组时,整个数组会被视为一个对象,因此转换后的List只包含一个元素(如List<int[]>),即该基本类型数组本身。所以如果是基本数据类型数组需要先转换为对应包装类型数组再转换成List。
- Ⅱ、返回的List不支持增删操作:返回一个固定大小的List,继承自AbstractList但没有重写add()和remove()等方法,增删元素的操作都会抛出UnsupportedOperationException异常。
- Ⅲ、修改操作会同时影响数组与List:返回的List是基于原始数组的视图,因此对原始数组的修改会反映到返回的List中,反之亦然。
- Ⅳ、返回的List类型不是java.util.ArrayList:返回的List是Arrays类的一个私有静态内部类ArrayList的实例,而不是java.util.ArrayList的实例。虽然都实现了List接口,但Arrays.ArrayList没有提供java.util.ArrayList的一些方法和特性(如clear()方法)。
- 2)、IntStream stream(int[] array):将数组转换为Stream流。
public class ArraysTest {
public static void main(String[] args) {
// 6、转换方法
// 1)、List<T> asList(T... a):将数组转换为List集合。
int[] array1 = {1, 2, 3, 4, 5};
List<int[]> list1 = Arrays.asList(array1); // 如果是基本数据类型则整个数组会被视为一个对象
Integer[] array2 = {1, 2, 3, 4, 5};
List<Integer> list2 = Arrays.asList(array2);
System.out.println("将数组转换为List集合:" + list1); // 输出[[I@5ebec15]
System.out.println("将数组转换为List集合:" + list2); // 输出[1, 2, 3, 4, 5]
// 2)、数组与流的转换
// 基本数据类型数组转换为Stream流
int[] array3 = {1, 2, 3};
IntStream intStream = Arrays.stream(array3);
double[] array4 = {1.2d, 2.3d, 3.4d};
DoubleStream doubleStream = Arrays.stream(array4);
System.out.println("基本数据类型数组转Stream:");
intStream.forEach(System.out::println); // 输出1,2,3
doubleStream.forEach(System.out::println); // 输出1.2, 2.3, 3.4
// 对象数组转换为Stream流
Person[] people = {
new Person("张三", 22),
new Person("李四", 33),
new Person("王五", 18)
};
System.out.println("对象数组转Stream:");
Stream<Person> personStream = Arrays.stream(people);
personStream.forEach(System.out::println); // 输出Person{name='张三', age=22}Person{name='李四', age=33}Person{name='王五', age=18}
}
}
7、数组复制方法:主要为copyOf()和copyOfRange()这两个方法,用于复制数组。
- 1)、int[] copyOf(int[] original, int newLength) :复制数组并指定新数组的长度,返回一个新数组。
- Ⅰ、如果newLength < 指定数组的长度时,则会将指定数组的前newLength个元素复制到新数组中。
- Ⅱ、如果newLength = 指定数组的长度时,则会将指定数组的全部元素复制到新数组中。
- Ⅲ、如果newLength > 指定数组的长度时,则会将指定数组的全部元素复制到新数组中,多余的索引位置的元素值同样是设置为默认值。
- 2)、int[] copyOfRange(int[] original, int from, int to):复制数组的指定索引范围的元素 [from, to),返回一个新数组。多余的索引位置的元素值同样是设置为默认值。
public class ArraysTest {
public static void main(String[] args) {
// 7、复制方法
// 1)、copyOf(int[] original, int newLength):复制数组并指定新数组的长度,返回一个新数组。
int[] nums = {1, 2, 3, 4, 5};
int[] copyNums1 = Arrays.copyOf(nums, 3);
int[] copyNums2 = Arrays.copyOf(nums, nums.length);
int[] copyNums3 = Arrays.copyOf(nums, 10);
System.out.println("复制数组的前3个元素:" + Arrays.toString(copyNums1)); // [1, 2, 3]
System.out.println("复制数组的全部元素:" + Arrays.toString(copyNums2)); // [1, 2, 3, 4, 5]
System.out.println("复制数组的全部元素,剩余元素设置为默认值:" + Arrays.toString(copyNums3)); // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
// 2)、copyOfRange(int[] original, int from, int to):复制数组的指定索引范围的元素 [from, to)。
int[] rangeCopy1 = Arrays.copyOfRange(nums, 2, 4);
System.out.println("复制数组中索引值在[2,4)范围内的元素:" + Arrays.toString(rangeCopy1)); // [3, 4]
int[] rangeCopy2 = Arrays.copyOfRange(nums, 1, 6);
System.out.println("复制数组中索引值在[1,6)范围内的元素:" + Arrays.toString(rangeCopy2)); // [2, 3, 4, 5, 0]
}
}
8、数组获取哈希码方法:主要用于获取数组的哈希码,分为一维数组和多为数组两种形式:
- 1)、int hashCode(int a[]):获取一维数组的哈希码。
- 2)、int deepHashCode(Object a[]):获取多维数组的哈希码。
public class ArraysTest {
public static void main(String[] args) {
// 8、获取哈希码方法
// 1)、int hashCode(int a[]):获取一维数组的哈希码。
int[] array = {1, 2, 3, 4, 5};
System.out.println(Arrays.hashCode(array)); // 输出哈希码29615266
// 2)、int deepHashCode(Object a[]):获取多维数组的哈希码。
int[][] deepArray = {{1, 2}, {3, 4}};
System.out.println(Arrays.hashCode(deepArray)); // 输出哈希码481388241
System.out.println(Arrays.deepHashCode(deepArray)); // 输出哈希码32833
}
}
9、找不同方法mismatch():用于比较两个相同长度(不相同会抛出 ArrayIndexOutOfBoundsException)的数组,并找出它们第一个不相等的元素在数组中的索引,如果两个数组相等,则返回 -1。对象数组中的元素比较使用 equals() 方法。
public class ArraysTest {
public static void main(String[] args) {
// 1)、基本数据类型数组比较:比较的是值
int[] array = {1, 2, 3, 4, 5};
int[] array1 = {1, 2, 3, 4, 5};
int[] array2 = {1, 2, 3, 6, 5};
System.out.println(Arrays.mismatch(array, array1)); // 输出-1
System.out.println(Arrays.mismatch(array1, array2)); // 输出3
long[] array3 = {1L, 2L, 3L, 4L, 5L};
long[] array4 = {1L, 2L, 3L, 6L, 5L};
System.out.println(Arrays.mismatch(array3, array4)); // 输出3
// 2)、对象数组比较:通过对象的equals()方法进行比较
String[] array7 = {"张三", "李四", "王五"};
String[] array8 = {"张三", "赵四", "王五"};
String[] array9 = {"张三", "李四", "王五"};
System.out.println(Arrays.mismatch(array7, array8)); // 输出1
System.out.println(Arrays.mismatch(array7, array9)); // 输出-1
System.out.println(Arrays.mismatch(array8, array9)); // 输出1
}
}
10、迭代器方法spliterator():用于从数组创建一个 Spliterator 实例的方法,在需要对数组进行并行处理时,能够显著提高处理效率。
public class ArraysTest {
public static void main(String[] args) {
// 10、获取迭代器方法:<T> Spliterator<T> spliterator(T[] array)
Integer[] array = {1, 2, 3, 4, 5};
Spliterator<Integer> spliterator = Arrays.spliterator(array);
spliterator.forEachRemaining(System.out::println); // 输出1,2,3,4,5
}
}