Java-Collection-集合使用注意事项


title: Java-Collection-集合使用注意事项
date: 2021-09-22 15:21:08
tags: Java
categories:

  • Java

集合转Map

在使用java.util.stream.Collectors类的toMap()方法转为Map集合时,一定要注意当value为null的时候会抛出NPE异常

class Person {
    private String name;
    private String phoneNumber;
     // getters and setters
}

List<Person> bookList = new ArrayList<>();
bookList.add(new Person("jack","18163138123"));
bookList.add(new Person("martin",null));
// 空指针异常
bookList.stream().collect(Collectors.toMap(Person::getName, Person::getPhoneNumber));

Person::getName意思就是调用Person类的GetName()方法

假设现在有个集合

List<User> users = getUserList();

现在需要把users里面每行数据的id提取出来。这个很简单,

for循环很容易想到.

List<Long> idList = new ArrayList<Long>();
for(int i = 0; i < users.size(); i++){
  idList.add(users.get(i).getId());
}

JDK8现在很简单一行代码搞定:

List<Long> idList = users.stream().map(User::getId).collect(Collectors.toList());

users.stream()获取集合的流对象,返回一个Stream

map(User::getId)遍历集合然后对集合里每一个对象执行getId方法,的到的返回值转化成一个新的集合,并返回这个集合的流

collect(Collectors.toList())通过集合器将集合对象的流转化成List类型的集合

集合转数组

《阿里巴巴 Java 开发手册》的描述如下:

使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。

toArray(T[] array) 方法的参数是一个泛型数组,如果 toArray 方法中没有传递任何参数的话返回的是 Object类 型数组。

String [] s= new String[]{
    "dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A"
};
List<String> list = Arrays.asList(s);
Collections.reverse(list);
//没有指定类型的话会报错
s=list.toArray(new String[0]);

由于 JVM 优化,new String[0]作为Collection.toArray()方法的参数现在使用更好,new String[0]就是起一个模板的作用,指定了返回数组的类型,0 是为了节省空间,因为它只是为了说明返回的类型。详见:https://shipilev.net/blog/2016/arrays-wisdom-ancients/

也就是说,list集合作为对象调用toArray转化成数组,需要声明一个参数为模板

类型与list定义的对象一致,且长度为0的空数组

易错点:

Arrays.asList()是泛型方法,数组只能是对象数组

int[] myArray = {1, 2, 3};
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));//数组地址值
System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException
int[] array = (int[]) myList.get(0);
System.out.println(array[0]);//1

但是我们使用包装类型就可以解决这个问题

Integer[] myArray = {1, 2, 3};

使用集合的修改方法: add()remove()clear()会抛出异常。

List myList = Arrays.asList(1, 2, 3);
myList.add(4);//运行时报错:UnsupportedOperationException
myList.remove(1);//运行时报错:UnsupportedOperationException
myList.clear();//运行时报错:UnsupportedOperationException

Arrays.asList() 方法返回的并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。

所以说.用List接口被Arrays.asList实例化只能用来查询,不能做修改操作

那我们如何正确的将数组转换为 ArrayList ?

1.最简便的方法
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
2.使用Java8的Stream(推荐)
Integer [] myArray = { 1, 2, 3 };
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 = { 1, 2, 3 };
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());
3.使用Guava

对于不可变集合,你可以使用ImmutableList类及其of()copyOf()工厂方法:(参数不能为空)

List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array

对于可变集合,你可以使用Lists类及其newArrayList()工厂方法:

List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs
4.使用 Apache Commons Collections
List<String> list = new ArrayList<String>();
CollectionUtils.addAll(list, str);
5.使用 Java9 的 List.of()方法
Integer[] array = {1, 2, 3};
List<Integer> list = List.of(array);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值