创建数组
1.copyOf:复制指定的数组,截取或用 null 填充
String[] intro = new String[] { "沉", "默", "王", "二" };
String[] revised = Arrays.copyOf(intro, 3);
String[] expanded = Arrays.copyOf(intro, 5);
System.out.println(Arrays.toString(revised));
System.out.println(Arrays.toString(expanded));
revised 和 expanded 是复制后的新数组,长度分别是 3 和 5,指定的数组长度是 4。来看一下输出结果:
[沉, 默, 王]
[沉, 默, 王, 二, null]
revised 截取了最后一位,因为长度是 3 嘛;expanded 用 null 填充了一位,因为长度是 5。
2.copyOfRange:复制指定范围内的数组到一个新的数组,null 进行填充
String[] intro = new String[] { "沉", "默", "王", "二" };
String[] abridgement = Arrays.copyOfRange(intro, 0, 3);
System.out.println(Arrays.toString(abridgement));
copyOfRange()
方法需要三个参数,第一个是指定的数组,第二个是起始位置(包含),第三个是截止位置(不包含)。
3.fill:对数组进行填充
String[] stutter = new String[4];
Arrays.fill(stutter, "沉默王二");
System.out.println(Arrays.toString(stutter));
使用 new 关键字创建了一个长度为 4 的数组,然后使用 fill()
方法将 4 个位置填充为“沉默王二”,来看一下输出结果:
[沉默王二, 沉默王二, 沉默王二, 沉默王二]
比较数组
Arrays 类的 equals()
方法用来判断两个数组是否相等
String[] intro = new String[] { "沉", "默", "王", "二" };
boolean result = Arrays.equals(new String[] { "沉", "默", "王", "二" }, intro);
System.out.println(result);
boolean result1 = Arrays.equals(new String[] { "沉", "默", "王", "三" }, intro);
System.out.println(result1);
输出结果如下所示:
true
false
简单看一下 equals()
方法的源码:
public static boolean equals(Object[] a, Object[] a2) {if (a==a2)return true;if (a==null || a2==null)return false;int length = a.length;if (a2.length != length)return false;for (int i=0; i<length; i++) {if (!Objects.equals(a[i], a2[i]))return false;}return true;
}
因为数组是一个对象,所以先使用“==”操作符进行判断,如果不相等,再判断是否为 null,其中一个为 null,返回 false;紧接着判断 length,不等的话,返回 false;否则的话,依次调用 Objects.equals()
比较相同位置上的元素是否相等。
数组排序
Arrays 类的 sort()
方法用来对数组进行排序:
String[] intro1 = new String[] { "chen", "mo", "wang", "er" };
String[] sorted = Arrays.copyOf(intro1, 4);
Arrays.sort(sorted);
System.out.println(Arrays.toString(sorted));
数组检索
数组排序后就可以使用 Arrays 类的 binarySearch()
方法进行二分查找了。否则的话,只能线性检索,效率就会低很多。
String[] intro1 = new String[] { "chen", "mo", "wang", "er" };
String[] sorted = Arrays.copyOf(intro1, 4);
Arrays.sort(sorted);
int exact = Arrays.binarySearch(sorted, "wang");
System.out.println(exact);
int caseInsensitive = Arrays.binarySearch(sorted, "Wang", String::compareToIgnoreCase);
System.out.println(caseInsensitive);
binarySearch()
方法既可以精确检索,也可以模糊检索,比如说忽略大小写。
数组转流
Arrays 类的 stream()
方法可以将数组转换成流:
String[] intro = new String[] { "沉", "默", "王", "二" };
System.out.println(Arrays.stream(intro).count());
还可以为 stream()
方法指定起始下标和结束下标:
System.out.println(Arrays.stream(intro, 1, 2).count());
数组转 List
尽管数组非常强大,但它自身可以操作的工具方法很少,比如说判断数组中是否包含某个值。如果能转成 List 的话,就简便多了。
String[] intro = new String[] { "沉", "默", "王", "二" };
List<String> rets = Arrays.asList(intro);
System.out.println(rets.contains("二"));
不过需要注意的是,Arrays.asList()
返回的是 java.util.Arrays.ArrayList
,并不是java.util.ArrayList
,它的长度是固定的,无法进行元素的删除或者添加。
要想操作元素的话,需要多一步转化,转成真正的 java.util.ArrayList
:
List<String> rets1 = new ArrayList<>(Arrays.asList(intro));
rets1.add("三");
rets1.remove("二");
setAll
Java 8 新增了 setAll()
方法,它提供了一个函数式编程的入口,可以对数组的元素进行填充:
int[] array = new int[10];
Arrays.setAll(array, i -> i * 10);
System.out.println(Arrays.toString(array));
i 就相当于是数组的下标,值从 0 开始,到 9 结束,那么 i * 10
就意味着值从 0 * 10 开始,到 9 * 10 结束,来看一下输出结果:
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
parallelPrefix
parallelPrefix()
方法和 setAll()
方法一样,也是 Java 8 之后提供的,提供了一个函数式编程的入口,通过遍历数组中的元素,将当前下标位置上的元素与它之前下标的元素进行操作,然后将操作后的结果覆盖当前下标位置上的元素。
int[] arr = new int[] { 1, 2, 3, 4};
Arrays.parallelPrefix(arr, (left, right) -> left + right);
System.out.println(Arrays.toString(arr));
输出结果:
1,2
3,3
6,4
[1, 3, 6, 10]
- 第一次是 1 和 2 相加,结果是 3,替换下标为 1 的位置
- 第二次是 3 和 3 相加,结果是 6,也就是第一次的结果和下标为 2 的元素相加的结果
- 第三次是 6 和 4 相加,结果是 10,也就是第二次的结果和下标为 3 的元素相加的结果