Arrays.asList 的坑 java.lang.UnsupportedOperationException/list剔除数据/UUID正确的生成方式,批量使用重复问题

  1. Arrays.asList

在项目中对List进行操作时报错java.lang.UnsupportedOperationException,后来发现操作的List是由数组转换而成的,通过看源码发现问题,并写测试程序如下。
代码块:

public class ListTest {
    public static void main(String[] args) {
        String[] array = {"1","2","3","4","5"};
        List<String> list = Arrays.asList(array);
        list.add("6");
    }
}

执行结果:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at com.atguigu.test.ListTest.main(ListTest.java:11)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

发生问题的原因如下:
调用Arrays.asList()生产的List的add、remove方法时报异常,这是由Arrays.asList() 返回的市Arrays的内部类ArrayList, 而不是java.util.ArrayList。Arrays的内部类ArrayList和java.util.ArrayList都是继承AbstractList,remove、add等方法AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。java.util.ArrayList重新了这些方法而Arrays的内部类ArrayList没有重新,所以会抛出异常。解决方法如下:

public class ListTest {
    public static void main(String[] args) {
        String[] array = {"1","2","3","4","5"};
        List<String> list = Arrays.asList(array);
        List arrList = new ArrayList(list);
        arrList.add("6");
    }
}

或者

	@Test
	public void test2021() {
		List<String> list = new ArrayList<>( Arrays.asList("1","2","3","4","7","8","9","ss","dsd","dsds","dsds","dsds"));		
		//一定要用arrayist
		list.remove(0);
		System.out.println(StringUtils.join(list.toArray()));
	}
  1. list查询剔除数据
    参考资料
    首先准备数据:
    public static List<User> createList(){
        List<User> result =new ArrayList<>();
        result.add(new User(1,"peter","123","二狗"));
        result.add(new User(2,"lilei","123","铁柱"));
        result.add(new User(3,"lilei","123","大炮"));
        result.add(new User(4,"jonhs","123","大虎"));
        return result;
    }```
剔除名字为lilei的数据
 错误的执行方式
 

```sql
    //从例表中剔除lilei的数据
    public static void main(String[] args) {
        List<User> list = createList();
        for(int i  = 0 ; i < list.size() ; i++){
            String temp = list.get(i).getUserName();
            if(temp.equals("lilei")){
                list.remove(i);
            }
        }
      }

执行结果为

[User{id=1, userName='peter', passWord='123', realName='二狗'}, User{id=3, userName='lilei', passWord='123', realName='大炮'}, User{id=4, userName='jonh', passWord='123', realName='大虎'}]

可见并没有剔除干净,从list中剔除数据最好使用迭代器 Iterator
正确的书写方式为:

        Iterator<User> iterator = list.iterator();
        while(iterator.hasNext()){
            User next = iterator.next();
            if(next.getUserName().equals("lilei")){
                iterator.remove();
            }
        }
        System.out.println(list.toString());

结果为

[User{id=1, userName='peter', passWord='123', realName='二狗'}, User{id=4, userName='jonhs', passWord='123', realName='大虎'}]

  1. UUID
    UUID在一般情况下是不会重复的 即使是用版本4 ,但是遇到批量操作的时候会产生重复,短时间内大量的调用该方法,造成了多线程调用,使多个数据获取到同一个UUID,造成UUID重复,就需要加synchronized同步锁来将同步改为异步,具体实现如下(包括多种版本实现方式,选取一种版本即可):

	//synchronized 同步锁  UUID一般是不会重复的 即使是用版本4 
	//但是当批量设置UUID时,短时间内大量的调用该方法,造成了多线程调用,使多个数据获取到同一个UUID,造成UUID重复
	@Test
	public synchronized void uuidTest() {
		// 最普遍的UUID 
		// version=4
		System.out.println(UUID.randomUUID().version());
		// 32位bd22291e39eb4736a55991497c6376d2
		System.out.println(UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
		// 基于时间的UUID 可以精确到毫微秒
		TimeBasedGenerator gen = Generators.timeBasedGenerator(EthernetAddress.fromInterface());
		UUID uuid = gen.generate();
		// version=1
		System.out.println(uuid.version());
		// 32位33304096c01311e58c16089e01cd1de9
		System.out.println(uuid.toString().replaceAll("-", "").toUpperCase());

		try {
			System.out.println(MD5Util.md5Encode(UUID.randomUUID().toString() + gen.generate().toString()));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PH = 7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值