关于 Arrays.asList()与Collections.shuffle()使用时的坑

今天使用Arrays.asList()这个方法碰见一个问题记录一下。

引入:

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");

废话少说,我们来看代码吧,

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()造成的问题。

代码例子如下:

 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()
 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只是实现了toArraygetsetindexOf等方法,并没有实现add()remove()方法,而是直接使用它的父类AbstractList的相应方法。
我们来看一下,他的父类AbstractList中关于addremove,进行了什么操作。

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,然后进行addremove操作是时会发生异常的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值