(Arrays.as..._java初始化list并赋值">
当前位置:   article > 正文

java初始化list并赋值_Java创建List、Map等集合对象的同时进行赋值操作

java初始化list并赋值

问题简介

在Java当中,若希望在创建数组的同时给数组赋值很简单,可以想下面这样:

int[] num = {1,2,3};

String strs = {"a", "b", "c"}

但是,如果我们创建List集合,或者Map集合时,也想快速地为它赋初始值,应当如何做呢?

解决方式

方式1:调用函数

请看如下代码:

ArrayList list = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));

  Arrays.asList(T... a) 方法的参数是一个可变长参数,也就是说他能够传入一个数组,也能够传入多个参数,而它的作用就是将传入的数组或多个数据封装成List集合返回,而上面的代码就是接收返回的List集合,并将其作为参数传入ArrayList的构造方法,创建一个新的ArrayList对象。

说到这里有人可能要问了,为什么不能直接将asList方法的返回值赋给list参数,而要将它传入构造器创建新的对象呢?这不是脱裤子放屁——多此一举吗。当然不是,请看下面的代码:

// 代码1

List list1 = Arrays.asList("aa", "bb", "cc");

list1.add("dd"); // UnsupportedOperationException

// 代码2

String[] str = {"a","b","c"};

List list = Arrays.asList(str);

str[0] = "e"; // list中的0号位置也一同改变

  上面有两段代码,看似没有问题,但是运行结果却和大家想象的有些不同。首先代码1,使用asList方法返回的创建的List对象,不允许进行修改操作,否则将会抛出一个UnsupportedOperationException;再来看代码2,我们将一个数组作为asList的参数,得到一个List对象,但是此时我们改变这个数组中元素的值,list对象的值也会发生改变,因为这个List对象底层引用的就是这个数组,并且和代码1一样,这个list也不能修改。

但是,若我们将返回的List对象作为参数传入ArrayList的构造器中,这个问题就不会发生,因为ArrayList的构造器将会把传入的list中所有的元素复制一份,因此不会影响到原数组,且可以随意改变。

方式2:匿名内部类

这是一个非常机智的方式,就是看到了下面这行代码,我才忍不住写了这篇博客:

List list = new ArrayList(){ {add("a"); add("b"); add("c");} };

乍一看是不是有点懵逼,我们将这段代码展开来看,就会清晰很多:

List list = new ArrayList() {

{

add("a");

add("b");

add("c");

}

};

这下应该比之前容易理解了。这段代码就是创建了一个匿名内部类对象,且这个类继承自ArrayList,在这个匿名内部类中添加了一个非静态代码块,并在代码块中调用了三次add方法,为这个List对象赋值。

我们知道,若我们想创建一个对象,可以直接new 构造方法,但是我们若想写一个匿名内部类,这个匿名内部类继承自某个类,只需在构造方法后面加上一对大括号。同时,非静态代码块会在构造方法执行前被执行,所以我们将赋值语句放在了代码块中,于是就有了上面这段代码。若还是看不明白,没关系,看下面这段代码十有八九就明白了,我们将上面的代码换另一种方式写出来:

public class Test {

public static void main(String[] args) {

List list = new MyList();

}

}

// 创建一个类继承自ArrayList

class MyList extends ArrayList{

// 在类的非静态代码块中编写赋值语句

{

add("a");

add("b");

add("c");

}

}

以上代码就是最开始那句代码的完整版,创建一个MyList类(名字随意),继承自ArrayList,并编写一个非静态代码块调用三次add方法,这个代码块将会在构造方法执行前被执行,因此创建一个MyList对象后,它肯定已经有三条数据了。若到此时还没有听懂,可能就需要去了解一下匿名内部类,以及代码块的执行机制了。

这种为集合赋值的好处就是,它可以用在任意一种集合类型上(Map,Set......),如下代码:

// 使用此方法为map赋值

HashMap map = new HashMap() {

{

put("a", 1);

put("b", 2);

put("c", 3);

}

};

当然,这种方法也有一些弊端,就拿ArrayList来说,那就是这种方法得到的对象,它的类型并不是ArrayList,我们调用对象.getClass().getName()方法获取对象的类名,得到的是代码所在类的类名+$1(这里和匿名内部类的机制有关,就不详细叙述了)。所以在代码中,如果对对象的类型有着严格的要求,就需要谨慎考虑是否应该使用这种方式。

博客总结

在平常编写代码时,还是第一种方式使用的比较多,因为简单而且不容易产生问题;而第二种方,我个人建议还是少用(虽然我就是为第二种方式写的博客.....),因为在类型要求严格的程序中,可能会产生问题。当然,第二种方式真的非常机智(感叹),而且可以用在各种类型的集合上,学习一下还是很有帮助的。

参考文献

《Java核心技术 卷Ⅰ》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/77372
推荐阅读
相关标签
  

闽ICP备14008679号