UnsupportedOperationException--数组转列表.操作列表出差

本文解析了Java集合框架中UnsupportedOperationException异常的原因,特别是在使用Arrays.asList方法时遇到的问题,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在使用collection框架code时,会时常遇到UnsupportedOperationException异常,有些人很不了解为什么抛出这个异常,会很郁闷,但是那些只知道code的代码工人不会想这些问题。下面我作一下解释,可能也不是很正确。

其实我们主要的疑惑可能是:java既然提供了这个方法,为什么我们调用要抛出异常,说不支持这个操作。我们先看一段代码:

  List list1 = new ArrayList();
  list1.add("test");
  
  String[] array = new String[2];
  List list2 = Arrays.asList(array);

  List list3 = new ArrayList(list2);
  list3.add("test");

  array[0] = "test2";
  System.out.println(list2.get(0));
  list2.add("test");//抛出异常
在执行到l2.add("test")时抛出如下异常:

test2
Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.AbstractList.add(AbstractList.java:151)
 at java.util.AbstractList.add(AbstractList.java:89)
 at TesException.main(TesException.java:20)

为什么会这样呢?

解释如下:

上面代码中list1是用正常方式下创建的List,可以增删内容

而list2是一个固定大小的List,不可以对其进行进行修改操作,对array的任何操作,若想修改list3的内容,只能通过修改其对应的array,从上面这一点也是可以看出的(关于这些解释可以参看api文档)。那么为什么会这样呢,其实List结构按是否可修改也是可以在分为两个类型的,但是collection框架已经有太多的接口类型了,若在对每种接口类型都分出一个unmodifiable类型的接口,那么最后collection框架会更大,对于学习与使用都会需要记住更多的接口。所以我想这样做的关键一点是:统一接口,减少开发人员的负担。但是若文档中没有对这一点说清楚,有些喜欢刨根问题的程序员会很郁闷。

我猜测Arrays.asList返回的List内容是Array的内容引用。若可以在List中修改,那么怎么同步呢?因为它们有一个本质的区别Array不能自动增大,若允许在List随便增大,则与其相应的Array的内容怎么保证不可修改呢?他们之间有一个阻抗。最后权衡一下,只能让Arrays.asList返回的List不可修改,或者让返回的List与Array之间没有关系,若这样的话,对于那些很大数组来说性能上就会很有影响。


查了一下发现是使用了Java里面未实现的方法,真晕。问题是这样的: 
我想把一串字符串eg: "123,4343,34543543",直接解析成List,然后删除其中的某一个元素,结果就出问题了,具体如下: 

Java代码  收藏代码
  1. String testStr = "100,300,400,545,666";  
  2. List<String> test = Arrays.asList(testStr.split(","));  
  3. test.remove("100");  


解决方案也简单就是不用呗,绕道: 
Java代码  收藏代码
  1. String testStr = "100,300,400,545,666";  
  2. List<String> test = new ArrayList<String>();  
  3. for(String t : testStr.split(",")){  
  4.         test.add(t);  
  5. }  
  6. test.remove("100");  

String cacheRuleKey = "ndmp-alarm-rule:" + msg.getMetric(); Object object = RedisBizUtil.getIfAbsent(cacheRuleKey, k -> { QueryWrapper<AlarmRule> qw = new QueryWrapper<>(); qw.eq("code", msg.getMetric()); log.info("alarm is-------->{}", JSONUtil.parseArray(alarmRuleMapper.selectList(qw))); return JSONUtil.parseArray(alarmRuleMapper.selectList(qw)); });这段代码总是报下面这个错,有什么解决办法,把所有办法都列出来,深度解析一下,详细一点org.springframework.data.redis.RedisSystemException: Unknown redis exception; nested exception is java.lang.UnsupportedOperationException: io.lettuce.core.output.StatusOutput does not support set(long) at org.springframework.data.redis.FallbackExceptionTranslationStrategy.getFallback(FallbackExceptionTranslationStrategy.java:53) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:43) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:278) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceConnection.await(LettuceConnection.java:1086) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceConnection.lambda$doInvoke$4(LettuceConnection.java:939) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceInvoker$Synchronizer.invoke(LettuceInvoker.java:673) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceInvoker$DefaultSingleInvocationSpec.get(LettuceInvoker.java:589) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.setEx(LettuceStringCommands.java:167) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.connection.DefaultedRedisConnection.setEx(DefaultedRedisConnection.java:335) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.DefaultValueOperations$8.potentiallyUsePsetEx(DefaultValueOperations.java:337) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.DefaultValueOperations$8.doInRedis(DefaultValueOperations.java:330) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:97) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:325) ~[spring-data-redis-2.7.3.jar!/:2.7.3] at com.kd.ndmp.pa.util.bizUtil.RedisUtil.set(RedisUtil.java:38) ~[classes!/:1.0-SNAPSHOT] at com.kd.ndmp.pa.util.bizUtil.RedisBizUtil.getIfAbsent(RedisBizUtil.java:319) ~[classes!/:1.0-SNAPSHOT] at com.kd.ndmp.pa.process.dealAlarm.DealAlarmData.dealAlarm(DealAlarmData.java:87) ~[classes!/:1.0-SNAPSHOT] at com.kd.ndmp.pa.process.executor.DcSyslogExecutor.sendMsg(DcSyslogExecutor.java:175) ~[classes!/:1.0-SNAPSHOT] at com.kd.ndmp.pa.process.executor.DcSyslogExecutor.run(DcSyslogExecutor.java:118) ~[classes!/:1.0-SNAPSHOT] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_151] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_151] at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_151] Caused by: java.lang.UnsupportedOperationException: io.lettuce.core.output.StatusOutput does not support set(long) at io.lettuce.core.output.CommandOutput.set(CommandOutput.java:107) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.RedisStateMachine.safeSet(RedisStateMachine.java:778) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.RedisStateMachine.handleInteger(RedisStateMachine.java:404) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.RedisStateMachine$State$Type.handle(RedisStateMachine.java:206) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.RedisStateMachine.doDecode(RedisStateMachine.java:334) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.RedisStateMachine.decode(RedisStateMachine.java:295) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:842) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.CommandHandler.decode0(CommandHandler.java:793) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:776) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:659) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:599) ~[lettuce-core-6.1.9.RELEASE.jar!/:6.1.9.RELEASE] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final] at io.netty.channel.AbstractChannelHandler 87行总报这个错,有什么解决办法吗
最新发布
07-29
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值