Java 创建 List 和 Map 同时赋初值的 5 种方式

举报
福州司马懿 发表于 2021/11/18 23:56:07 2021/11/18
【摘要】 一、最常见的初始化方式 先创建,再添加元素 List 从源码可以看出: List 的默认长度为10递增后的长度为先前长度的 1.5 倍最大长度是 Integer.MAX_VALUE,即 2,147...

一、最常见的初始化方式

先创建,再添加元素

List

从源码可以看出:

  • List 的默认长度为10
  • 递增后的长度为先前长度的 1.5 倍
  • 最大长度是 Integer.MAX_VALUE,即 2,147,483,647 或 0x7f ff ff ff
List<String> list = new ArrayList<>();
list.add("str1");
list.add("str2");
list.add("str3");

  
 
  • 1
  • 2
  • 3
  • 4

当元素是静态对象时,可以使用静态代码块在初始化时进行赋值

private static List<String> static_list = new ArrayList<>();
static {
    static_list.add("str1");
    static_list.add("str2");
    static_list.add("str3");
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Map

从源码可以看出:

  • hashMap 的初始长度为 16
  • 递增后的长度为之前的 2 倍
  • 最大长度是 1<<30 - 1,即 1,073,741,824‬ - 8 或 0x40 00 00 00 - 1
Map<String, String> map = newHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");

  
 
  • 1
  • 2
  • 3
  • 4

当元素是静态对象时,可以使用静态代码块在初始化时进行赋值

private static Map<String, String> static_map = new HashMap<>();
static {
    static_map.put("key1", "value1");
    static_map.put("key2", "value2");
    static_map.put("key3", "value3");
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

二、使用双花括号在初始化的同时赋值

外层的 {} 定义了一个匿名内部类。内层的 {} 定义了一个实例初始化代码块。这个代码块在初始化内部类时执行。所以这里相当于定义了一个匿名内部类,并使用 add 添加元素来初始化。

但这种方式有几个缺点:

  1. 使用匿名内部类,会有效率上的损失。当然在大多数情况下,这点效率都是可接受的。
  2. 静态内部类持有所在外部类的引用。如果需要将 List 返回给到其他地方使用,可能造成内存泄漏。

List

List<String> list = new ArrayList<String>() {
 {
        add("str1");
        add("str2");
        add("str3");
}};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Map

Map<String, String> map = new HashMap<String, String>() {
{
        put("key1", "value1");
        put("key2", "value2");
        put("key3", "value3");
}};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

三、利用Arrays工具类

List

Arrays.asList使用了静态内部类,该类继承自 AbstractList,实现了 RandomAccess,内部使用了一个数组来存储元素。注意:内部定义的 ArrayList 并没有实现 List 接口,所以也不支持修改元素。

ArrayList(E[] array) {
	a = Objects.requireNonNull(array);
}
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

查看源码可以发现,虽然 Arrays 和 ArrayList 都是在 java.utils 包下,但它们创建的 ArrayList 确是两个同名,但不同的东西。

Arrays 中声明了一个ArrayList 的内部类,但是该类不支持增删元素,如果使用了诸如 add 方法,在编译时不会报错,但运行时会报 UnsupportedOperationException
在这里插入图片描述
由于 Arrays 的 asList 方法使用了 “变长参数列表”,因此即使直接使用多个字符串作为参数,在编译时也会被自动装包成数组。

List<String> list1 = Arrays.asList(new String[] {"str1 ", "str2", "str3"});

List<String> list2 = Arrays.asList("str1 ", "str2", "str3");

  
 
  • 1
  • 2
  • 3

四、利用Lists工具类

List

List 工具类提供了一个 newArrayList 的静态方法,从源码可以看出,newArrayList 实际只是对 ArrayList 无参初始化方法的封装,然后通过遍历迭代器 Iterator,将迭代器中的所有元素加入 List 而已

public static <E> ArrayList<E> newArrayList(final Iterator<? extends E> iterator) {
	final ArrayList<E> list = newArrayList();
	Iterators.addAll(list, iterator);
	return list;
}
public static <E> ArrayList<E> newArrayList() {
	return new ArrayList<>();
}
public static <T> boolean addAll(final Collection<T> collection, final Iterator<? extends T> iterator) {
	Objects.requireNonNull(collection);
	Objects.requireNonNull(iterator);
	boolean wasModified = false;
	while (iterator.hasNext()) {
	    wasModified |= collection.add(iterator.next());
	}
	return wasModified;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Lists 提供了两个方法:一个是创建一个空列表;一个是创建空列表的同时遍历迭代器,将它的值添加到列表中。

List<String> list = Lists.newArrayList();
list1.add("str1");
list1.add("str2");
list1.add("str3");

  
 
  • 1
  • 2
  • 3
  • 4

注意:这里并不能用双花括号表达式直接添加元素

List<String> list = Lists.newArrayList(list.iterator());

  
 
  • 1

五、利用Collections工具类

List

创建一个固定长度的 CopiesList,List 长度不能改变,且元素都一样,且也是不可改变的。Java在实现时,仅使用了一个空间,用来存存放元素,当N足够大时,可以节省空间和性能。

同样,和 Arrays 创建的 List 一样,都没有实现 List 接口,因此使用add方法,同样会在编译时报错java.lang.UnsupportedOperationException
在这里插入图片描述

CopiesList<String> list1 = Collections.nCopies(5, "str");

  
 
  • 1

此外,Collections 还提供了一个为 List 一次性添加所有元素的方法,弥补了原先 List 只能添加 Collections,而不支持数组的缺憾。

List<String> list2 = new ArrayList<>();
Collections.addAll(list1, new String[]{"str1", "str2", "str3"});
Collections.addAll(list1, "str4", "str5", "str6");

  
 
  • 1
  • 2
  • 3

六、流式转化

流是 Java8 的新特性,提供了一种类似 SQL 语句从数据库中查询数据的方式,通过封装好的函数和链式调用,高阶抽象并简化操作。

它可以对传入流内部的元素进行筛选、排序、聚合等中间操作(intermediate operate),最后由最终操作(terminal operation)得到前面处理的结果。

通过静态的 Stream.of 方法接收元素,然后通过 collect 方法处理得到最终结果。

List

List<String> list1 = Stream.of("str1", "str2", "str3").collect(Collectors.toList());

  
 
  • 1

Map

Collectors.toMap() 知识点:
在这里插入图片描述

  • Java 8 中我们可以通过 :: 关键字来访问类的构造方法,对象方法,静态方法。
  • Java8 允许在接口中加入具体方法,接口中的具体方法有两种,default 方法和 static 方法,identity () 就是 Function 接口的一个静态方法。Function.identity() 是一个返回一个跟输入一样的 Lambda 表达式对象,形式为 t -> t
    在这里插入图片描述
  • 第三个参数是合并函数,如果不指定 mergeFunction,当存在两个 key 相同的元素时,会报 java.lang.IllegalStateException: Duplicate key g1 at java.util.stream.Collectors.lambda$throwingMerger 错误。
    1. key相同时当前值替换原始值
      (oldVal, currVal) -> currVal
    2. key相同时保留原始值
      (oldVal, currVal) -> oldVal

Test.java

Map<String, Book> map = books.stream()
	.sorted(Comparator.comparing(Book::getISBN))
	.collect(Collectors.toMap(Book::getISBN, Function.identity(), (oldVal, currVal) -> oldVal));

  
 
  • 1
  • 2
  • 3

Book.java

public class Book {
    public String name;
    public String author;
    public float price;
    public String ISBN;

    public Book(String name, String author, float price, String ISBN) {
        this.name = name;
        this.author = author;
        this.price = price;
        this.ISBN = ISBN;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String getISBN() {
        return ISBN;
    }

    public void setISBN(String ISBN) {
        this.ISBN = ISBN;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

文章来源: blog.csdn.net,作者:福州-司马懿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/chy555chy/article/details/103983753

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。