前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于 Arrays.asList()与Collections.shuffle()使用时的坑

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

作者头像
易帜
发布2022-02-09 16:09:41
5260
发布2022-02-09 16:09:41
举报
文章被收录于专栏:易帜的Android 学习之旅

今天使用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) 返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。) 此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素:

代码语言:javascript
复制
 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的结构:

代码语言:javascript
复制
 private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable{
        .....
        }

我们从源码中可以看出,该ArrayList只是实现了toArraygetsetindexOf等方法,并没有实现add()remove()方法,而是直接使用它的父类AbstractList的相应方法。 我们来看一下,他的父类AbstractList中关于addremove,进行了什么操作。

代码语言:javascript
复制
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操作是时会发生异常的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引入:
    • 深入了解一下Arrays.asList()
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档