List遍历抛出UnsupportedOperationException在Android不同版本上不同表现

昨天遇到个问题,对字符串按照自然顺序排序,比如说"abd03156"->"01356abd"

最开始是这么写的:

val toList = newValue.toList()
Collections.sort(toList)
var result = ""
for (i in toList) {
    result += i
}

newValue设置的初始值为“0“

上面的代码在7.0的手机上崩溃了,在8.0和9.0的手机上木有问题

报错信息如下:

 Caused by: java.lang.UnsupportedOperationException
        at java.util.AbstractList.set(AbstractList.java:681)
        at java.util.AbstractList$FullListIterator.set(AbstractList.java:143)
        at java.util.Collections.sort(Collections.java:1882)
        at com.test.databindingdemo.MainActivity$$special$$inlined$observable$1.afterChange(Delegates.kt:73)
        at kotlin.properties.ObservableProperty.setValue(ObservableProperty.kt:41)
        at com.test.databindingdemo.MainActivity.setGetServerDataStatus(MainActivity.kt)
        at com.test.databindingdemo.MainActivity.onCreate(MainActivity.kt:65)

后来临时改成了这样就木有问题了。

val toCharArray = newValue.toCharArray()

Arrays.sort(toCharArray)

val result = String(toCharArray)

可是为什么呢?看日志应该是Collections的sort函数有问题,看代码发现个提示

猜测:kotlin的toList函数的返回值是个不可更改的List,如果需要返回可更改的List需要使用toMutableList,但是为什么在8.0和9.0的手机上木有问题呢?

看Collections的sort函数代码

public static <T> void sort(List<T> list, Comparator<? super T> c) {
        // BEGIN Android-changed: Compat behavior for apps targeting APIs <= 25.
        // list.sort(c);
        int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
        if (targetSdkVersion > 25) {
            list.sort(c);
        } else {
            // Compatibility behavior for API <= 25. http://b/33482884
            if (list.getClass() == ArrayList.class) {
                Arrays.sort((T[]) ((ArrayList) list).elementData, 0, list.size(), c);
                return;
            }

            Object[] a = list.toArray();
            Arrays.sort(a, (Comparator) c);
            ListIterator<T> i = list.listIterator();
            for (int j = 0; j < a.length; j++) {
                i.next();
                i.set((T) a[j]);
            }
        }
        // END Android-changed: Compat behavior for apps targeting APIs <= 25.
    }

7.0的sort代码和上面else里的代码一样

 public static <T extends Comparable<? super T>> void sort(List<T> list) {
        if (list.getClass() == ArrayList.class) {
            Arrays.sort(((ArrayList) list).elementData, 0, list.size());
            return;
        }

        Object[] a = list.toArray();
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }
    }

单个字符的字符串toList转换成的对象为Collections$SingletonList

而多字符的字符串toList转换成的对象为ArrayList

7.1(sdk 25)以上的代码里是执行的List的sort方法,如果是Collections$SingletonList,那就执行Collections$SingletonList.sort()方法,如果是ArrayList,那么就执行ArrayList的sort()方法。Collections$SingletonList这个类重写了sort方法(空实现,方法里啥都没有),所以不会造成崩溃,一个字符不用排序啊!

但是7.1及以下的代码里用Iterator做里遍历,而这个遍历导致里崩溃。再说下为什么会崩溃,Iterator的set方法如下,调用里AbstractList的set方法,这个方法直接抛出了异常。

 public void set(E object) {
            if (expectedModCount == modCount) {
                try {
                    AbstractList.this.set(lastPosition, object);
                } catch (IndexOutOfBoundsException e) {
                    throw new IllegalStateException();
                }
            } else {
                throw new ConcurrentModificationException();
            }
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UnsupportedOperationException是一个运行时异常,在Android开发中通常表示不支持的操作。它是由Java编程语言中的java.lang.UnsupportedOperationException抛出的。 该异常通常发生在尝试执行不被支持的操作时,例如调用不支持的方法、访问不支持的功能或尝试进行不支持的数据转换。在Android开发中,可能会遇到以下几种情况导致UnsupportedOperationException抛出: 1. 在某些特定的Android设备或Android版本中,某些方法可能不被支持。当我们在代码中调用这些不支持的方法时,就会抛出UnsupportedOperationException。 2. 尝试对不可变集合进行修改操作。在Java中,不可变集合是指一旦创建就不能修改的集合对象,例如Arrays.asList返回的List。如果我们尝试对不可变集合进行修改操作,就会抛出UnsupportedOperationException。 3. 在Android开发中,使用SqliteDatabase或ContentProvider操作SQLite数据库时,可能会遇到不支持的操作。这可能是因为数据库的模式或结构发生了变化,或者某些操作不被允许。 要解决UnsupportedOperationException,可以根据具体情况采取以下措施: 1. 确保使用的方法在目标设备或版本上是被支持的。可以查询相关的文档或检查设备或Android版本的兼容性。 2. 避免对不可变集合进行修改操作,可以创建一个新的集合对象并进行必要的修改。 3. 重新设计数据库模式或结构,以兼容不同的操作。 总之,UnsupportedOperationExceptionAndroid开发中表示不支持的操作,需要根据具体情况进行对应的处理措施,以确保代码的稳定性和正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值