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
    评论
使用Java Collection时,有一些需要注意的事项。首先,如果你想要在遍历集合时移除元素,需要使用迭代器的remove()方法而不是直接使用集合的remove()方法,否则会抛出ConcurrentModificationException异常。这是因为直接使用集合的remove()方法会修改集合的结构,而在遍历过程中不能修改集合的结构。 另外,需要注意的是,在使用<foreach>进行集合遍历时,属性的格式应该正确,例如正确使用<foreach>标签和属性,如无法正确使用属性,可能会导致遍历失败。 对于List和Set集合而言,使用<foreach>进行遍历的方法是一样的,所以可以统一使用<foreach>进行遍历List集合。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java Collection 移除元素方法注意事项](https://download.csdn.net/download/weixin_38528463/12743970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Mybatis中XML中传不同类型的参数时,collection注意事项](https://blog.csdn.net/m0_51697147/article/details/126686680)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值