ArraysCollections是分别操作数组和集合的两个工具类。今天就来对 Arrays 中的内容作个总结。

Arrays 类位于 java.util包中。Arrays 继承 Object

  1. java.lang.Object
  2. java.util.Arrays

Arrays 类中的静态方法可以对数组进行排序、查询、搜索等等操作。

该方法返回一个 ArrayList , 其返回的 ArrayList 从下面的代码可以看出不是我们平常 new 出来的动态可扩展的 ArrayList。可以看这篇 ArrayList

  1. @SafeVarargs
  2. @SuppressWarnings("varargs")
  3. public static <T> List<T> asList(T... a) {
  4. return new ArrayList<>(a);
  5. }
  6. /**
  7. * @serial include
  8. */
  9. private static class ArrayList<E> extends AbstractList<E>
  10. implements RandomAccess, java.io.Serializable
  11. {
  12. private static final long serialVersionUID = -2764017481108945198L;
  13. private final E[] a;
  14. ArrayList(E[] array) {
  15. a = Objects.requireNonNull(array);
  16. }
  17. @Override
  18. public int size() {
  19. return a.length;
  20. }
  21. @Override
  22. public Object[] toArray() {
  23. return a.clone();
  24. }
  25. @Override
  26. @SuppressWarnings("unchecked")
  27. public <T> T[] toArray(T[] a) {
  28. int size = size();
  29. if (a.length < size)
  30. return Arrays.copyOf(this.a, size,
  31. (Class<? extends T[]>) a.getClass());
  32. System.arraycopy(this.a, 0, a, 0, size);
  33. if (a.length > size)
  34. a[size] = null;
  35. return a;
  36. }
  37. @Override
  38. public E get(int index) {
  39. return a[index];
  40. }
  41. @Override
  42. public E set(int index, E element) {
  43. E oldValue = a[index];
  44. a[index] = element;
  45. return oldValue;
  46. }
  47. @Override
  48. public int indexOf(Object o) {
  49. E[] a = this.a;
  50. if (o == null) {
  51. for (int i = 0; i < a.length; i++)
  52. if (a[i] == null)
  53. return i;
  54. } else {
  55. for (int i = 0; i < a.length; i++)
  56. if (o.equals(a[i]))
  57. return i;
  58. }
  59. return -1;
  60. }
  61. @Override
  62. public boolean contains(Object o) {
  63. return indexOf(o) != -1;
  64. }
  65. @Override
  66. public Spliterator<E> spliterator() {
  67. return Spliterators.spliterator(a, Spliterator.ORDERED);
  68. }
  69. @Override
  70. public void forEach(Consumer<? super E> action) {
  71. Objects.requireNonNull(action);
  72. for (E e : a) {
  73. action.accept(e);
  74. }
  75. }
  76. @Override
  77. public void replaceAll(UnaryOperator<E> operator) {
  78. Objects.requireNonNull(operator);
  79. E[] a = this.a;
  80. for (int i = 0; i < a.length; i++) {
  81. a[i] = operator.apply(a[i]);
  82. }
  83. }
  84. @Override
  85. public void sort(Comparator<? super E> c) {
  86. Arrays.sort(a, c);
  87. }
  88. }
  1. public static void main(String[] args) {
  2. //创建一个数组
  3. int[] a = {1,2,3};
  4. //new 一个 ArrayList
  5. ArrayList<Integer> list = new ArrayList<>();
  6. list.add(1);
  7. list.add(2);
  8. list.add(3);
  9. System.out.println(list);//[1, 2, 3]
  10. System.out.println(a); //[I@1540e19d
  11. System.out.println(Arrays.toString(a));//[1, 2, 3]
  12. /*如果将基本数据类型的数组作为参数传入,该方法会把整个数组当成一个元素*/
  13. System.out.println(Arrays.asList(a));//[[I@1540e19d]
  14. System.out.println(Arrays.asList(1,2,3));//[1, 2, 3]
  15. }

对数组所有元素进行升序排序,没有返回值。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.sort(a);
  3. System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 5, 6, 7, 8, 9]

对数组特定序列进行升序排序,从 [fromIndex, endIndex]区域的数组元素进行排序

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.sort(a,0,5);
  3. System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 9, 5, 6, 7, 8]

利用自定义的比较器,来对数组元素进行排序

  1. // Java program to demonstrate working of Comparator
  2. // interface
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6. // A class to represent a student.
  7. class Student {
  8. int rollno;
  9. String name, address;
  10. // Constructor
  11. public Student(int rollno, String name,
  12. String address)
  13. {
  14. this.rollno = rollno;
  15. this.name = name;
  16. this.address = address;
  17. }
  18. // Used to print student details in main()
  19. public String toString()
  20. {
  21. return this.rollno + " "
  22. + this.name + " "
  23. + this.address;
  24. }
  25. }
  26. //自定义的比较器,对两个对象的 rollno 属性进行比较
  27. class Sortbyroll implements Comparator<Student> {
  28. // Used for sorting in ascending order of
  29. // roll number
  30. public int compare(Student a, Student b)
  31. {
  32. return a.rollno - b.rollno;
  33. }
  34. }
  35. // Driver class
  36. class Main {
  37. public static void main(String[] args)
  38. {
  39. Student[] arr = { new Student(1, "bbbb", "london"),
  40. new Student(3, "aaaa", "nyc"),
  41. new Student(2, "cccc", "jaipur") };
  42. System.out.println("Unsorted-未排序前");
  43. for (int i = 0; i < arr.length; i++)
  44. System.out.println(arr[i]);
  45. Arrays.sort(arr, new Sortbyroll());
  46. System.out.println("\nSorted by rollno-排序后");
  47. for (int i = 0; i < arr.length; i++)
  48. System.out.println(arr[i]);
  49. }
  50. }
  51. /** 输出结果:
  52. *Unsorted-未排序前
  53. *1 bbbb london
  54. *3 aaaa nyc
  55. *2 cccc jaipur
  56. *
  57. *Sorted by rollno-排序后
  58. *1 bbbb london
  59. *2 cccc jaipur
  60. *3 aaaa nyc
  61. *
  62. **/

利用自定义的比较器,来对数组中指定范围元素进行排序

把4中代码换成

  1. Arrays.sort(arr, 1, 2, new Sortbyroll());//对第一、二个元素进行比较
  2. /** 输出结果:
  3. *Unsorted-未排序前
  4. *1 bbbb london
  5. *3 aaaa nyc
  6. *2 cccc jaipur
  7. *
  8. *Sorted by rollno-排序后
  9. *1 bbbb london
  10. *3 aaaa nyc
  11. *2 cccc jaipur
  12. *
  13. **/

对数组元素进行升序排序,当数据规模较大时,性能更好(并行排序)。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.parallelSort(a);
  3. System.out.println(Arrays.toString(a));//[1, 2, 3, 4, 9, 5, 6, 7, 8]

用 fillValue 值来填充数组。前一个函数填充所有,后面的函数填充指定范围。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.fill(a,1);//[1, 1, 1, 1, 1, 1, 1, 1, 1]
  3. Arrays.fill(a,1,3,1);//[1, 1, 1, 9, 4, 5, 6, 7, 8]

判断两个数组是否相等, 返回布尔值

equals()主要针对基本数据和Object 一维数组,其比较规则如下:

  1. if (a==a2)
  2. return true;
  3. if (a==null || a2==null)
  4. return false;
  5. int length = a.length;
  6. if (a2.length != length)
  7. return false;
  8. for (int i=0; i<length; i++) {
  9. Object o1 = a[i];
  10. Object o2 = a2[i];
  11. if (!(o1==null ? o2==null : o1.equals(o2)))
  12. return false;
  13. }
  14. return true;

deepEquals()主要是多维数组的比较,其比较规则为:

  1. if (a1 == a2)
  2. return true;
  3. if (a1 == null || a2==null)
  4. return false;
  5. int length = a1.length;
  6. if (a2.length != length)
  7. return false;
  8. for (int i = 0; i < length; i++) {
  9. Object e1 = a1[i];
  10. Object e2 = a2[i];
  11. if (e1 == e2)
  12. continue;
  13. if (e1 == null)
  14. return false;
  15. // Figure out whether the two elements are equal
  16. boolean eq = deepEquals0(e1, e2);
  17. if (!eq)
  18. return false;
  19. }
  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. int[] b = {1,2};
  3. int[][] c = {{1,2},{1,3}};
  4. int[][] d = {{1,2},{1,3}};
  5. Arrays.equals(a,b);//false
  6. Arrays.equals(c,d);//true

返回该数组的哈希值

前面一个函数是返回一维数组,后面是多维数组

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. int[][] c = {{1,2},{1,3}};
  3. System.out.println(Arrays.hashCode(a));//887857437
  4. System.out.println(Arrays.deepHashCode(c));//31776

方法一:在数组中对某值进行二分查找(注意要先对数组排序!),如果存在返回其下标,否则返回 -(数组极值下标 +1)。

方法二:方法中的参数限定数组的范围,Comparator 是自定义的比较器

  1. int[] a = {1,2,3,4,5,9,6,7,8};
  2. Arrays.sort(a);
  3. System.out.println(Arrays.binarySearch(a,1));//0
  4. System.out.println(Arrays.binarySearch(a,0));//-1
  5. System.out.println(Arrays.binarySearch(a,10));//-10

方法一:拷贝数组,newLength 是拷贝的长度,如果超过原数组的长度,则用 null 进行填充。并返回一个新数组。

方法二:拷贝数组,fromIndex 和 endIndex 是数组的范围下标。并返回一个新数组。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. System.out.println(Arrays.toString(Arrays.copyOf(a,3)));//[1,2,3]
  3. System.out.println(Arrays.toString(Arrays.copyOfRange(a,0,3)));//[1,2,3]

返回数组元素的字符串形式,方法一是一维数组,方法二是多维数组。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. System.out.println(Arrays.toString(a));//[1,2,3,9,4,5,6,7,8]
  3. int[][] c = {{1,2},{3}};
  4. System.out.println(Arrays.deepToString(c));//[[1, 2], [3]]

方法一:将数组中的所有元素,串行的使用方法提供的生成器函数来计算每个元素(一元操作)

方法二:将数组中的所有元素,串行的使用方法提供的生成器来计算每个元素(一元操作)适用于大规模数据

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.setAll(a, i -> a[i] * 2);
  3. System.out.println(Arrays.toString(a));//[2,4,6,18,8,10,12,14,16]
  4. Arrays.parallelSetAll(a, i -> a[i] * 2);
  5. System.out.println(Arrays.toString(a));//[2,4,6,18,8,10,12,14,16]

方法一:将数组中所有元素,并行使用生成器函数来计算每个元素(二元操作)

方法二:将数组中部分序列元素,并行使用生成器函数来计算每个元素(二元操作)

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Arrays.parallelPrefix(a, (x,y) -> x*y);//依次累乘
  3. System.out.println(Arrays.toString(a));//[1, 2, 6, 54, 216, 1080, 6480, 45360, 362880]
  4. Arrays.parallelPrefix(a, 0, 3, (x,y) -> x*y);//依次累乘
  5. System.out.println(Arrays.toString(a));//[1, 2, 6, 9, 4, 5, 6, 7, 8]

返回数组的分片迭代器,用于并行的遍历数组

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. Spliterator<Integer> s = Arrays.spliterator(a);
  3. s.forEachRemaining(System.out::println);
  4. /**
  5. *
  6. *1
  7. *2
  8. *3
  9. *9
  10. *4
  11. *5
  12. *6
  13. *7
  14. *8
  15. **/

返回数组的流,可以对数组使用 Stream 相关的方法。

  1. int[] a = {1,2,3,9,4,5,6,7,8};
  2. List<Integer> list = Arrays.stream(a).collect(toList());
  3. System.out.println(list);//[1,2,3,9,4,5,6,7,]

Arrays class in Java

Java Collections – Arrays.spliterator() Example

Arrays 类常用方法解析

版权声明:本文为EthanWong原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/EthanWong/p/15240299.html