今天使用Arrays.asList()这个方法碰见一个问题记录一下。
引入:
代码语言:javascript复制Java.util.Collections类下有一个静态的shuffle()方法,如下:
1)static voidshuffle(List<?> list) 使用默认随机源对列表进行置换,所有置换发生的可能性都是大致相等的。 2)static voidshuffle(List<?> list, Random rand) 使用指定的随机源对指定列表进行置换,所有置换发生的可能性都是大致相等的,假定随机源是公平的。
java.util.Arrays类中有一个静态的asList()方法,如下: public static List asList(T… a) 返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。) 此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
废话少说,我们来看代码吧,
代码语言:javascript复制public static void main(String[] args) {
Integer[] temp={1,2,3,45,6,6,456,7,8};
List<Integer> list= Arrays.asList(temp);
System.out.println("list:更改前:" list);
Collections.shuffle(list);
System.out.println("list:更改后:" list);
System.out.println("---------------");
List<Integer> list2= Arrays.asList(temp);
System.out.println("list2:更改前list:" list);
System.out.println("list2:更改前list2:" list2);
Collections.shuffle(list2);
System.out.println("list2:更改后list:" list);
System.out.println("list2:更改前list:" list2);
}
其打印结果为:
什么鬼东西,打印结果表示两个List内容相同?? 难道是这两个list的地址相同了吗? 随后进行比较:
地址不一致?那么是什么情况造成这种结果呢? 通过查阅资料发现。
如果给定一个整型数组,用Arrays.asList()方法将其转化为一个集合类,有两种途径:
1)用List list=ArrayList(Arrays.asList(temp)),用shuffle()打乱不会改变底层数组的顺序。
2)用List list=Arrays.aslist(temp),然后用shuffle()打乱会改变底层数组的顺序。
这么一看,清楚明了,是我错误的使用了Arrays.asList()造成的问题。
代码例子如下:
代码语言:javascript复制 public static void main(String[] args) {
Integer[] temp={1,2,3,45,6,6,456,7,8};
List<Integer> list=Arrays.asList(temp);
System.out.println("list:更改前" list);
Collections.shuffle(list);
System.out.println("list:更改后" list);
System.out.println("---------------");
List<Integer> list2= Arrays.asList(temp);
System.out.println("list2:更改前" list2);
System.out.println("list2:更改前list" list);
Collections.shuffle(list2);
System.out.println("list2:更改后" list2);
System.out.println("list2:更改前list" list);
System.out.println("---------------");
List<Integer> list3= new ArrayList<>(Arrays.asList(temp));
System.out.println("list3:更改前list" list);
System.out.println("list3:更改前list2" list2);
System.out.println("list3:更改前list3" list3);
Collections.shuffle(list3);
System.out.println("list3:更改后list" list);
System.out.println("list3:更改后list2" list2);
System.out.println("list3:更改后list3" list3);
}
运行结果如下:
同过上述代码可以更加清晰的看出来。两种数组转List
的方法造成不同的效果。
深入了解一下Arrays.asList()
代码语言:javascript复制 public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
此处需要注意,asList()
返回的是ArrayList
并不是java.util
包下的,而是java.util.Arrays.ArrayList
,
我们在来看看java.util.Arrays.ArrayList
的结构:
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable{
.....
}
我们从源码中可以看出,该ArrayList只是实现了toArray
、get
、set
、indexOf
等方法,并没有实现add()
、remove()
方法,而是直接使用它的父类AbstractList
的相应方法。
我们来看一下,他的父类AbstractList
中关于add
、remove
,进行了什么操作。
public void add(int index, @libcore.util.NullFromTypeParam E element) {
throw new RuntimeException("Stub!");
}
@libcore.util.NullFromTypeParam public E remove(int index) {
throw new RuntimeException("Stub!");
}
可以得知,我们直接使用Arrays.asList()
获取到的List
,然后进行add
、remove
操作是时会发生异常的。