Arrays类

  • ​​1、Arrays类​​
  • ​​1.1 toString方法:转换字符串​​
  • ​​1.2 sort方法:自然排序​​
  • ​​1.3 sort方法:定制排序​​
  • ​​1.4 binarySearch:查找​​
  • ​​1.5 copyOf方法:数组复制​​
  • ​​1.6 equals方法:判断数组的元素是否相等​​
  • ​​1.7 案例:左奇右偶​​

1、Arrays类

  为了简化对数组的操作,JDK1.2在​​java.util​​包下增加了一个Arrays类(数组工具类),里面提供了一系列静态方法,用于对数组进行排序、查找等。Arrays类常见方法如表所示。

序号

方法定义

描述

1

​String toString(int[] arr)​

将数组各元素进行拼接,最终返回数组格式的字符串

2

​void sort(int[] arr)​

对指定的int型数组按数字升序进行排序

3

​void sort(Object[] a)​

根据元素的自然顺序对指定对象数组按升序进行排序

4

​void sort(Object[] a,Comparator c)​

根据指定比较器产生的顺序对指定对象数组进行排序

5

​int binarySearch(int[] arr.int key)​

通过二分查找法,搜索有序的arr数组中是否存在key元素,返回索引,如果找不到则返回负数。如果数组无序,则结果不确定。

6

​int binarySearch(Object[] a,Object key)​

使用二分搜索法来搜索指定数组,以获得指定对象。在进行此调用之前,必须根据元素的自然顺序对数组进行升序排序(通过​​sort(Object[] obj)​​方法)。如果没有对数组进行升序排序,则结果是不确定的。

7

​int binarySearch(Object[] a,Object key,Comparator c)​

使用二分搜索法来搜索指定数组,以获得指定对象。在进行此调用之前,必须根据同一个比较器(通过​​sort(Object[] obj,Comparator c)​​方法)对数组进行升序排序。如果没有对数组进行排序,则结果是不确定的。

8

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

赋值数组,返回的新数组长度是newLength

9

​boolean equals(int[] a1,int[] a2)​

判断两个数组的元素是否都相等

10

​boolean equals(Object[] a,Object[] a2)​

判断两个数组的元素是否都相等,依赖于元素的​​equals​​方法

  上述方法提供了多种重载形式,除了支持int[],还支持其他各种类型的数组,甚至也支持对象数组,这里就不再赘述了。

1.1 toString方法:转换字符串

  使用数组存储数据之后,查看所有数组元素是最基本的需求,之前我们不得不使用for循环进行遍历。有了Arrays类之后,可以使用Arrays的​​toString​​​方法,快速地返回数组的所有元素内容。该方法返回的字符串格式为​​[元素1,元素2,...]​​,该方法为重载方法,参数类型支持任意类型的数组。

import java.util.Arrays;

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

Arrays类_数据结构

1.2 sort方法:自然排序

  对数组元素的排序可谓能难倒一堆初学者,但是如果不谈实现代码,仅从实现排序效果来说还是非常简单的。Arrays类提供了sort方法用于对各种类型的数组进行升序排序

  排序一般分为自然排序定制排序

  自然排序,是指基本数据类型的数组就是按照数值本身的大小进行排序;对象数组的自然排序就是元素本身已经实现​​java.lang.Comparable​​​接口的​​compareTo​​方法,即对象本身具有了可比较性,所以在排序时,按着元素本身的比较规则(compareTo方法的实现)进行排序。该方法为重载方法,支持除boolean类型的任意类型元素。

  下面分别以常用的整型数组和对象数组类型为例,进行代码演示。

  案例1:整数数组的自然排序

import java.util.Arrays;

/**
* 整数数组的自然排序
*/
public class ArraysSortTest1 {
public static void main(String[] args) {
int[] arr={5,2,1,4,3};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}

Arrays类_数组_02

  案例2:对象数组的自然排序,以Person[]为例,当然需要先定义好Person类。

import java.util.Objects;

public class Person implements Comparable{
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = 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 +
'}';
}

//重写compareto方法-按年龄比较大小
@Override
public int compareTo(Object o) {
Person p=(Person) o;
return this.age-p.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 age == person.age &&
Objects.equals(name, person.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

  测试类示例代码:

import java.util.Arrays;

/**
* 对象数组的自然排序
*/
public class ArraysSortTest2 {
public static void main(String[] args) {
Person[] pers={
new Person("john",12),
new Person("john1",23),
new Person("john2",5),
new Person("john3",20),
new Person("john4",18),
};
Arrays.sort(pers);
for (Person per : pers) {
System.out.println(per);
}
}
}

Arrays类_算法_03

   如果Person类没有实现Comparable接口,则会抛出ClassCastException(类型转换异常),因为​​Arrays.sort​​​方法底层会将Person元素进行转型,转换为Comparable接口类型然后调用​​compareTo​​方法。

  前面我们学习的八大包装类型、String类型都已经实现了Comparable接口,所以可以直接排序。

1.3 sort方法:定制排序

  定制排序,是指不管数组元素本身是否已经实现​​Comparable​​​接口的​​compareTo​​方法,在排序时都是用定制比较器的比较规则进行排序。

  定制比较器是指​​java.util.Comparator​​​接口的实现类对象,包含抽象方法​​int compare(Object obj1,Object obj2)​​,定制排序器只支持对象数组。

  下面以Person[]为例进行演示,Person类是否实现Comparable接口并无要求,具体代码如下:

import java.util.Objects;

public class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = 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 +
'}';
}
}

  测试类示例代码:

import java.util.Arrays;
import java.util.Comparator;

/**
* sort方法:定制排序
*/
public class ArraysSortTest3 {
public static void main(String[] args) {
Person[] pers={
new Person("john",12),
new Person("lily",23),
new Person("lucy",5),
new Person("jack",20),
new Person("rose",18),
};
System.out.println("按照年龄排序:");
Arrays.sort(pers, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
for (Person per : pers) {
System.out.println(per);
}

System.out.println("按照姓名排序:");
Arrays.sort(pers, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getName().compareTo(o2.getName());
}
});

for (Person per : pers) {
System.out.println(per);
}
}
}

   这块对Lambda表达式比较熟悉的话,可以重构一下上面的代码。

Arrays类_数组_04

  上述代码使用匿名内部类的方式实现了​​Comparator​​接口,使得代码更紧凑。

1.4 binarySearch:查找

  二分查找的效率远远高于顺序查找。Arrays类提供了二分查找的直接实现方法​​binarySearch​​,我们直接调用即可。当然该方法返回正确结果的前提是待查找的数组已经排好序,否则结果是不确定的。对象数组要求元素必须支持自然排序或指定了定制比较器对象。

  下面以整型数组为例,进行代码演示。

import java.util.Arrays;

public class BinarySearchTest {
public static void main(String[] args) {
int[] arr={1,3,5,7,9};
System.out.println("5在数组中的下标:"+ Arrays.binarySearch(arr,5));
}
}

Arrays类_java_05

1.5 copyOf方法:数组复制

  数组扩容等操作通常都涉及数组的复制操作,Arrays类的​​copyOf​​​方法和​​copyOfRange​​方法可以满足不同场合的排序。

  下面以常用的整型数组为例,进行代码演示。

import java.util.Arrays;

public class CopyOfTest {
public static void main(String[] args) {
int[] a={5,2,1,4,3};

int[] newArr1= Arrays.copyOf(a,a.length-2);
System.out.println("长度为原数组长度-2的新数组:"+Arrays.toString(newArr1));

int[] newArr2= Arrays.copyOf(a,a.length+2);
System.out.println("长度为原数组长度+2的新数组:"+Arrays.toString(newArr2));
}
}

Arrays类_System_06

1.6 equals方法:判断数组的元素是否相等

  如果需要比较两个数组的元素是否完全相等,那么可以直接使用Arrays类的​​equals​​方法来比较,该方法为重载方法,参数类型支持任意类型的数组。如果是基本数据类型,则直接比较数组的长度和元素值;如果是引用数据类型,则比较数组的长度及每个元素的equals方法。

  下面以对象数组为例,进行代码演示。

  Person类代码:

import java.util.Objects;

public class Person{
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = 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 +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

  测试类示例代码:

import java.util.Arrays;

/**
* equals方法:判断数组元素是否相等
*/
public class ArraysEqualsTest {
public static void main(String[] args) {
Person[] arr1={
new Person("john",12),
new Person("lily",23),
new Person("lucy",5),
new Person("jack",20),
new Person("rose",18),
};
Person[] arr2={
new Person("john",12),
new Person("lily",23),
new Person("lucy",5),
new Person("jack",20),
new Person("rose",18),
};
System.out.println(Arrays.equals(arr1,arr2));
}
}

Arrays类_System_07

1.7 案例:左奇右偶

  案例需求:现在有一个长度为10的数组{26,67,49,38,52,66,7,71,56,87},先要求将所有的奇数放在数组的左侧,所有的偶数放在数组的右侧,并且把所有的奇数实现从小到大排列,所有的偶数也实现从小到大排列,结果如{7,49,67,71,87,26,38,52,56,66}。

import java.util.Arrays;
public class OddLeftEvenRight {
public static void main(String[] args) {
int[] arr={26,67,49,38,52,66,7,71,56,87};
int left=0;
int right=arr.length-1;
while(left<right){
while(arr[left]%2!=0){
left++;
}
while(arr[right]%2==0){
right--;
}
if(left<right){
int temp=arr[left];
arr[left]=arr[right];
arr[right]=temp;
}
}
Arrays.sort(arr,0,left);
Arrays.sort(arr,right+1,arr.length);
System.out.println(Arrays.toString(arr));
}
}

Arrays类_java_08