欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Arrays 工具类

程序员文章站 2024-03-06 10:06:55
...

本人博客园链接 https://www.cnblogs.com/zongmin/p/11339000.html

数组转集合asList

  • 将数组转换为集合,接收一个可变参数
<T> List<T> asList(T... a);
public static void main(String[] args) {
    List<Integer> list1 = Arrays.asList(1, 2, 3);
    list1.forEach(System.out::println);  // 1 2 3

    Integer[] data = {1, 2, 3};
    List<Integer> list2 = Arrays.asList(data);
    list2.forEach(System.out::println); // 1 2 3
}

注意:该方法返回的是 Arrays 内部静态类 ArrayList,而不是我们平常使用 java.util.List 包下的 ArrayList。由于该静态类的底层采用大小固定的数组,所以任何对该 list 的添加、删除操作都会抛出异常。


填充数组fill

  • 用指定元素填充整个数组
//有多个不同数据类型的重载方法,此处列出一个
void fill(Object[] a, Object val);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    Arrays.fill(data, 5);
    System.out.println(Arrays.toString(data)); // [5, 5, 5, 5]
}
  • 用指定元素填充数组,从 fromIndex 位置开始(包括)到 toIndex 位置结束(不包括)
//有多个不同数据类型的重载方法,此处列出一个
public static void fill(Object[] a, int fromIndex, int toIndex, Object val);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    Arrays.fill(data, 0, 2, 5);
    System.out.println(Arrays.toString(data)); // [5, 5, 3, 4]
}

排序sort/parallelSort

  • 对数组元素从小到大进行排序。对于元素类型为基本类型,采用一种快速排序算法,该排序算法是不稳定的;对于元素类型为引用类型,采用归并排序,该排序算法是稳定的。
//有多个不同数据类型的重载方法,此处列出一个
void sort(Object[] a)
public static void main(String[] args) {
    String[] data = {"1", "4", "3", "2"};
    System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]
    Arrays.sort(data);
    System.out.println(Arrays.toString(data)); // [1, 2, 3, 4]
}
  • 对 fromIndex 位置开始(包括)开始到 toIndex 位置结束(不包括)的数组元素进行排序。
//有多个不同数据类型的重载方法,此处列出一个
void sort(Object[] a, int fromIndex, int toIndex);
public static void main(String[] args) {
    String[] data = {"1", "4", "3", "2"};
    System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]
    Arrays.sort(data, 0, 3);
    System.out.println(Arrays.toString(data)); // [1, 3, 4, 2]
}
  • 使用自定义比较器,对数组元素进行排序
void sort(T[] a, Comparator<? super T> c);
public static void main(String[] args) {
    String[] data = {"1", "4", "3", "2"};
    System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]

    // 实现字典序降序排列
    // 比较器返回大于1,o1大于o2,换位置;返回0,相等;返回负数,o1小于o2,位置不变
    Arrays.sort(data, (o1, o2) -> o2.compareTo(o1));
    System.out.println(Arrays.toString(data)); // [4, 3, 2, 1]
}
  • 使用自定义比较器,对 fromIndex 位置开始(包括)开始到 toIndex 位置结束(不包括)的数组元素进行排序
void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c)
public static void main(String[] args) {
    String[] data = {"1", "4", "3", "2"};
    System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]

    // 实现字典序降序排列
    // 比较器返回大于1,o1和o2换位置;返回0,相等;返回负数,不变
    Arrays.sort(data, 0, 3, (o1, o2) -> o2.compareTo(o1));
    System.out.println(Arrays.toString(data)); // [4, 3, 1, 2]
}
  • 上面的情况都是单核(串行)进行排序,下列方式是多核(并行)进行排序,当数据规模较大时,会有更好的性能,其余重载方法和上面类似。
public static <T extends Comparable<? super T>> void parallelSort(T[] a)
public static void main(String[] args) {
    String[] data = {"1", "4", "3", "2"};
    System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]

    Arrays.parallelSort(data);
    System.out.println(Arrays.toString(data)); // [1, 2, 3, 4]
}

查找binarySearch

  • 使用二分法查找正序的数组 a 中的指定元素 key,如果在数组中找到该元素,返回该元素的索引值;如果未查找到该元素,返回 -(最后一次查找的索引值 + 1),因此返回负数即为查找未成功。
//有多个不同数据类型的重载方法,此处列出一个
int binarySearch(Object[] a, Object key);

//a 数组必须已经根据 Comparator 排好序
int binarySearch(T[] a, T key, Comparator<? super T> c);
public static void main(String[] args) {
    Integer[] data = {1, 5, 3, 7};
    //查找前的数组必须是正序的
    Arrays.sort(data);
    System.out.println(Arrays.toString(data));  //[1, 3, 5, 7]

    System.out.println(Arrays.binarySearch(data, 3)); //1

    //查找小于数组最小元素的数
    //程序会把数组看作 {0, 1, 3, 5, 7},此时0的索引值为0,则搜索0时返回 -(0 + 1) = -1
    System.out.println(Arrays.binarySearch(data, 0)); //-1

    //查找大于数组最大元素的数
    //程序会把数组看作 {1, 3, 5, 7, 10},此时10的索引值为4,则搜索10时返回 -(5 + 1) = -5
    System.out.println(Arrays.binarySearch(data,  10)); //-5
    
    //查找不是数组元素,但在数组范围内的数
    //程序会把数组看作 {1, 3, 5, 6, 7},此时6的索引值为3,则搜索10时返回 -(3 + 1) = -4
    System.out.println(Arrays.binarySearch(data, 6));  //-4
}
  • 使用二分法查询数组从 fromIndex 位置开始(包括)开始到 toIndex 位置结束(不包括)范围内的指定元素的索引值。
//有多个不同数据类型的重载方法,此处列出一个
int binarySearch(Object[] a, int fromIndex, int toIndex, Object key);

//a 数组必须已经根据 Comparator 排好序
int binarySearch(T[] a, int fromIndex, int toIndex, T key, Comparator<? super T> c);
public static void main(String[] args) {
    Integer[] data = {1, 5, 3, 7};
    //查找前的数组必须是正序的
    Arrays.sort(data);
    System.out.println(Arrays.toString(data));  //[1, 3, 5, 7]

    System.out.println(Arrays.binarySearch(data, 0, 2, 3)); //1
    
    //程序会把数组看作 {0, 1, 3},此时0的索引值为0,则搜索0时返回 -(0 + 1) = -1
    System.out.println(Arrays.binarySearch(data, 0, 2, 0)); //-1
    
    //程序会把数组看作 {1, 3, 10},此时10的索引值为2,则搜索10时返回 -(2 + 1) = -3
    System.out.println(Arrays.binarySearch(data, 0, 2, 10)); //-3
}

拷贝数组copyOf/copyOfRange/arraycopy

  • 拷贝数组,其内部调用了 System.arraycopy() 方法,从下标 0 开始,如果超过原数组长度,则会用 null 进行填充。
//有多个不同数据类型的重载方法,此处列出一个
T[] copyOf(T[] original, int newLength);
public static void main(String[] args) {
    Integer[] data1 = {5, 4, 3, 2};

    Integer[] data2 = Arrays.copyOf(data1, 2);
    System.out.println(Arrays.toString(data2)); // [5, 4]

    Integer[] data3 = Arrays.copyOf(data1, 5);
    System.out.println(Arrays.toString(data3)); // [5, 4, 3, 2, null]
}
  • 拷贝从 from 位置开始(包括)开始到 to 位置结束(不包括)范围内的数组元素,如果超过原数组长度,则会用 null 进行填充。
//有多个不同数据类型的重载方法,此处列出一个
T[] copyOfRange(T[] original, int from, int to);
public static void main(String[] args) {
    Integer[] data1 = {5, 4, 3, 2};

    Integer[] data2 = Arrays.copyOfRange(data1, 0, 2);
    System.out.println(Arrays.toString(data2)); // [5, 4]

    Integer[] data3 = Arrays.copyOfRange(data1, 0, 5);
    System.out.println(Arrays.toString(data3)); // [5, 4, 3, 2, null]
}
  • arraycopy 不是 Arrays 类的方法,而是 System 类。该方法可以将 src 数组里从 srcPos 开始的 length 个的元素拷贝给 dest 数组的元素,destPos 是 dest 数组的赋值起始位置。
void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
public static void main(String[] args) {
    Integer[] data1 = {5, 4, 3, 2, 1};
    Integer[] data2 = new Integer[5];

    System.arraycopy(data1, 1, data2, 0, 3);

    System.out.println(Arrays.toString(data1));  //[5, 4, 3, 2, 1]
    System.out.println(Arrays.toString(data2));  //[4, 3, 2, null, null]
}

判断相等equals/deepEquals

  • 判断两个数组是否相等,如果 a 和 a2 指向同一个数组对象,返回 true; 如果 a 和 a2 指向不同的数组对象,对于基本类型元素直接判断它们是否相等,对于引用类型元素调用它们的 equals 方法进行比较,都为 true,最终才返回true。
//有多个不同数据类型的重载方法,此处列出一个
boolean equals(Object[] a, Object[] a2);
public static void main(String[] args) {
    Integer[] data1 = {1, 2, 3};
    Integer[] data2 = {1, 2, 3};
    
    System.out.println(Arrays.equals(data1, data2)); // true
    //数组对象没有重写equals方法,默认判断的是data1 == data2,是否为同个数组对象引用
    System.out.println(data1.equals(data2));  //false
}
  • 判断两个多维数组是否相等,判断方式和 equals 差不多。
boolean deepEquals(Object[] a1, Object[] a2);
public static void main(String[] args) {
    Integer[][] data1 = {{1,2,3}, {1,2,3}};
    Integer[][] data2 = {{1,2,3}, {1,2,3}};
    System.out.println(Arrays.deepEquals(data1, data2)); // true
}

返回哈希值hashCode/deepHashCode

  • 该方法计算并返回数组的哈希值
//有多个不同数据类型的重载方法,此处列出一个
int hashCode(Object a[]);
public static void main(String[] args) {
    Integer[] data1 = {1, 2, 3};
    Integer[] data2 = {1, 2, 3};

    System.out.println(Arrays.hashCode(data1));  //30817
    //数组对象没有重写hashCode方法,默认返回的是地址的哈希值
    System.out.println(data1.hashCode());   //460141958

	System.out.println(Arrays.hashCode(data2));  //30817
    System.out.println(data2.hashCode());   //1163157884
}
  • 该方法计算并返回多维数组的哈希值
int deepHashCode(Object a[]);
public static void main(String[] args) {
    Integer[][] data1 = {{1, 2, 3}, {1, 2, 3}};
    Integer[][] data2 = {{1, 2, 3}, {1, 2, 3}};

    System.out.println(data1.hashCode());   //460141958
    System.out.println(Arrays.deepHashCode(data1));  //987105

    System.out.println(data2.hashCode());   //1163157884
    System.out.println(Arrays.deepHashCode(data2));  //987105
}

字符串格式toString/deepToString

  • 该方法将一个数组转换成一个字符串,多个数组元素使用英文逗号和空格隔开。要求该数组的引用类型元素重写了 toString() 方法,因为该方法拼接的是元素的 toString() 返回值。
//有多个不同数据类型的重载方法,此处列出一个
String toString(Object[] a);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3};
    
    System.out.println(Arrays.toString(data)); // [1, 2, 3]
    //数组对象没有重写toString方法,默认返回的是地址的哈希值
    System.out.println(data.toString());  //[Ljava.lang.Integer;@1b6d3586
}
  • 返回多维数组的字符串格式。
String deepToString(Object[] a);
public static void main(String[] args) {
    Integer[][] data = {{1, 2, 3}, {1, 2, 3}};
    System.out.println(Arrays.deepToString(data)); // [[1, 2, 3], [1, 2, 3]]
}

元素生成器setAll/parallelSetAll

  • 让数组中的所有元素,串行使用方法提供的生成器函数来计算每个元素。
//有多个不同数据类型的重载方法,此处列出一个
void setAll(T[] array, IntFunction<? extends T> generator);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    // i为数组索引值
    Arrays.setAll(data, i -> data[i] * 2);
    System.out.println(Arrays.toString(data)); // [2, 4, 6, 8]
}
  • 让数组中的所有元素,并行使用方法提供的生成器函数来计算每个元素,当数据规模较大时,会有更好的性能。
//有多个不同数据类型的重载方法,此处列出一个
void parallelSetAll(T[] array, IntFunction<? extends T> generator);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    // i为索引值
    Arrays.parallelSetAll(data, i -> data[i] * 2);
    System.out.println(Arrays.toString(data)); // [2, 4, 6, 8]
}

数组转Stream对象stream

  • 该方法将数组转换为 Stream, Stream 是 JDK 1.8 新增的流式编程的 API。
//有多个不同数据类型的重载方法,此处列出一个
Stream<T> stream(T[] array);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    List<Integer> list = Arrays.stream(data).collect(toList());
    System.out.println(list);  //[1, 2, 3, 4]
}
  • 该方法将从 startInclusive 位置开始(包括)开始到 endExclusive 位置结束(不包括)范围内的数组元素转换为 Steam。
//有多个不同数据类型的重载方法,此处列出一个
Stream<T> stream(T[] array, int startInclusive, int endExclusive);
public static void main(String[] args) {
    Integer[] data = {1, 2, 3, 4};
    List<Integer> list = Arrays.stream(data, 0, 3).collect(toList());
    System.out.println(list); // [1, 2, 3]
}

参考: https://blog.csdn.net/Goodbye_Youth/article/details/81003817