Arrays类

举报
别团等shy哥发育 发表于 2023/01/08 17:53:21 2023/01/08
【摘要】 @toc 1、Arrays类  为了简化对数组的操作,JDK1.2在java.util包下增加了一个Arrays类(数组工具类),里面提供了一系列静态方法,用于对数组进行排序、查找等。Arrays类常见方法如表所示。序号方法定义描述1String toString(int[] arr)将数组各元素进行拼接,最终返回数组格式的字符串2void sort(int[] arr)对指定的int型数组...

@toc

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));
    }
}

image-20221007124027502

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));
    }
}

image-20221007124544324

  案例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);
        }
    }
}

image-20221007124706400

   如果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表达式比较熟悉的话,可以重构一下上面的代码。

image-20221007125855999

  上述代码使用匿名内部类的方式实现了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));
    }
}

image-20221007130433831

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));
    }
}

image-20221007130559922

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));
    }
}

image-20221007131010854

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));
    }
}

image-20221007131252763

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。