Arrays工具类

数组转集合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

转载于:https://www.cnblogs.com/zongmin/p/11339000.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值