1、正常创建一个List,对List进行操作
List<Integer> collect = Stream.of(1 ,3 ,5 ,7 ,9).collect(Collectors.toList());
//第一位改变为9
collect.set(0, 9);
//尾部插入一个值
collect.add(99);
collect.forEach(System.out::println);
//output
9
3
5
7
9
99
2、有时候为了更加方便的创建List,使用Arrays.asList
2.1 出现情况
List<Integer> asList = Arrays.asList(1 ,3 ,5 ,7 ,9);
asList.set(0,9);
//asList.add(99);
asList.forEach(System.out::println);
//output
9
3
5
7
9
//把上述注释放开
oops~报错了
2.2 原因分析
直接点入asList这个方法,查看源码,发现这个通过Arrays.asList创建出来的List是继承这个AbstractList的
分析源码发现,此时的ArrayList有set的复用,当时并没有add方法的复用,所以默认就是采用父类的方法了,我们再点进去父类分析
最终找到这个方法,所以就是为什么使用Arrays.asList创建出来的list使用set,当时使用add方法就会报错
2.3 解决方案
//使用new ArrayList()包装一下
3、还有情况就是想创建一个不可变的List,不能set更改值,也不能add增加值,“只读”情况
3.1 出现情况
3.2 原因分析
使用Collections.unmodifiableList方法包装List之后,重新生成的List是不能修改的,这点我们通过源码去观察一下
- 第一步走到了这里,如果list List集合具备快速随机访问的能力(实现RandomAccess接口),then new 第一个list
- 否则就是new 第二个list
- 但是其实,第一个是继承了第二个的,所以我们直接去第二个list(UnmodifiableList中)查看一下源码
可以发现,无论是set或者是add,甚至是remove,sort,均会抛出异常
也就是说,通过这个包装方法得到的list集合,是只读的,不可变的,正如方法名所说的一样
3.3 适用场景
模拟一个大型购物商场,顾客选择完自己想要购买的商品,到售货员哪里进行结算的流程
抽象出来两个角色:顾客和售货员
/**
* 模拟顾客购买商品的流程
*
* @author Amg
* @date 2021/9/8 10:01
*/
public class Customer {
private List<Long> ids;
Customer() {
ids = new ArrayList<>();
}
/**
* 添加商品
* @param goodsId 商品主键id
*/
public void add(Long goodsId) {
ids.add(goodsId);
}
/**
* 移除商品
* @param goodsId 商品主键id
*/
public void remove(Long goodsId) {
ids.remove(goodsId);
}
/**
* 返回最终的商品列表
* @return List<Long>
*/
public List<Long> getIds() {
return ids;
}
}
/**
* 售货员
* @author Amg
* @date 2021/9/8 10:18
*/
public class Sales {
private List<Long> list;
public Sales(List<Long> goodsId) {
list = goodsId;
}
/**
* 结算
*/
public double countPrice() {
double price = 0;
for (Long id : list) {
//根据list里面的商品获取价格,这里简单先模拟
if (id % 2 == 0) {
price += 1;
} else {
price += 2;
}
}
return price;
}
}
/**
* 商场客户端
* @author Amg
* @date 2021/9/8 10:17
*/
public class Client {
public static void main(String[] args) {
Customer customer = new Customer();
//添加商品
customer.add(123L);
customer.add(456L);
customer.add(789L);
//移除商品
customer.remove(123L);
List<Long> ids = customer.getIds();
Sales sales = new Sales(ids);
System.out.println(sales.countPrice());
}
}