每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

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~报错了

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

2.2 原因分析

直接点入asList这个方法,查看源码,发现这个通过Arrays.asList创建出来的List是继承这个AbstractList

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

分析源码发现,此时的ArrayList有set的复用,当时并没有add方法的复用,所以默认就是采用父类的方法了,我们再点进去父类分析

最终找到这个方法,所以就是为什么使用Arrays.asList创建出来的list使用set,当时使用add方法就会报错

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

2.3 解决方案

//使用new ArrayList()包装一下

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

3、还有情况就是想创建一个不可变的List,不能set更改值,也不能add增加值,“只读”情况

3.1 出现情况

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

3.2 原因分析

使用Collections.unmodifiableList方法包装List之后,重新生成的List是不能修改的,这点我们通过源码去观察一下

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

  1. 第一步走到了这里,如果list List集合具备快速随机访问的能力(实现RandomAccess接口),then new 第一个list
  2. 否则就是new 第二个list
  3. 但是其实,第一个是继承了第二个的,所以我们直接去第二个list(UnmodifiableList中)查看一下源码

可以发现,无论是set或者是add,甚至是remove,sort,均会抛出异常

每日一记:关于Arrays.asList和Collections.unmodifiableList的一点理解

也就是说,通过这个包装方法得到的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());
	}
}

上一篇:Java-- Arrays操纵数组的工具类


下一篇:cocos2d-x在win7下的环境配置