Java 数组操作

值得注意的数组操作

相等


由于数组自身没有重写过equals方法,直接比较数组等同于a==b,并非想要的结果

Sample
1
2
3
int[] a = { 1, 2, 3 },b = { 1, 2, 3 };
System.out.println(a.equals(b)); //false
System.out.println(Arrays.equals(a, b)); //true

因此如果想使用set尝试来对数组去重是不行的

Sample
1
2
3
4
5
int[] a = {1,2,3}, b = {1,2,3};
Set<int[]> s = new HashSet<>();
s.add(a);
s.add(b);
System.out.println(s.size()); //2

Arrays静态比较,标准是数组等长且对应位置相等

Arrays.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static boolean equals(int[] a, int[] 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 (a[i] != a2[i])
return false;
return true;
}

转字符串


Sample
1
2
3
int[] a = { 1, 2, 3 };
System.out.println(a.toString()); //[I@7852e922
System.out.println(Arrays.toString(a)); //[1, 2, 3]

Arrays内部使用StringBuilder循环遍历构建

Arrays.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static String toString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";

StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}

转列表


Arrays提供asList方法,可以转列表

如果传入数组,实际上整个数组被当成整体

Sample
1
2
3
int[] a = { 1, 2, 3 };
System.out.println(Arrays.asList(a).size()); //1
List<Integer> d = Arrays.asList(a); //Error 转换后为List<Integer[]>

底层实现基于泛型不定参数,泛型把数组作为类型

Arrays.java
1
2
3
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}

转之后发现无法追加数据

Sample
1
2
3
4
5
6
7
8
List<Integer> b = new ArrayList<Integer>();
b.add(1);
b.add(2);
b.add(3);
b.add(4);

List<Integer> a = Arrays.asList(1, 2, 3);
a.add(4); // java.lang.UnsupportedOperationException

表面上返回了ArrayList,但这个ArrayList并非常用的那个,而是Arrays内部单独定义的内部类
内部类是个简化版的实现,只实现基本get/set, 无法改动容量

总结

  • 使用asList要避免把数组作为参数
  • 返回的List是特殊的, 无法进行操作