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);