java.lang.UnsupportedOperationException分析及解决

这篇具有很好参考价值的文章主要介绍了java.lang.UnsupportedOperationException分析及解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        今天在写业务的时候,需要对从数据库返回的List集合根据对象属性进行排序,那么常规的做法就是使用Collections的sort方法,实现Compartor接口重写compare方法,或者直接使用该list的sort方法,但是无论使用那种方法都遇到了这样的报错原因: 

java.lang.UnsupportedOperationException: null
	at java.util.Collections$UnmodifiableList.sort(Collections.java:1333) ~[na:1.8.0_331]
	at java.util.Collections.sort(Collections.java:177) ~[na:1.8.0_331]

         无法支持的操作,再看报错第二行UnmodifiableList,这是一个不可变的集合,它继承 UnmodifiableCollection类,UnmodifiableCollection 中涉及到元素改动(新增、删除、清空…)的方法都直接抛出 UnsupportedOperationException 异常,并不改动元素;Iterator 中涉及到元素修改的方法也一样不进行元素的改动。

        那么是不是把这个集合变成可变的集合问题是不就解决了呢?

list = new ArrayList<>(list);

         在排序前给这个list再次封装,问题得以解决。

static class UnmodifiableList<E> extends UnmodifiableCollection<E>
                                  implements List<E> {
        private static final long serialVersionUID = -283967356065247728L;

        final List<? extends E> list;

        UnmodifiableList(List<? extends E> list) {
            super(list);
            this.list = list;
        }

        public boolean equals(Object o) {return o == this || list.equals(o);}
        public int hashCode()           {return list.hashCode();}

        public E get(int index) {return list.get(index);}
        public E set(int index, E element) {
            throw new UnsupportedOperationException();
        }
        public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
        public E remove(int index) {
            throw new UnsupportedOperationException();
        }
        public int indexOf(Object o)            {return list.indexOf(o);}
        public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
        public boolean addAll(int index, Collection<? extends E> c) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            throw new UnsupportedOperationException();
        }
        @Override
        public void sort(Comparator<? super E> c) {
            throw new UnsupportedOperationException();
        }

        public ListIterator<E> listIterator()   {return listIterator(0);}

        public ListIterator<E> listIterator(final int index) {
            return new ListIterator<E>() {
                private final ListIterator<? extends E> i
                    = list.listIterator(index);

                public boolean hasNext()     {return i.hasNext();}
                public E next()              {return i.next();}
                public boolean hasPrevious() {return i.hasPrevious();}
                public E previous()          {return i.previous();}
                public int nextIndex()       {return i.nextIndex();}
                public int previousIndex()   {return i.previousIndex();}

                public void remove() {
                    throw new UnsupportedOperationException();
                }
                public void set(E e) {
                    throw new UnsupportedOperationException();
                }
                public void add(E e) {
                    throw new UnsupportedOperationException();
                }

                @Override
                public void forEachRemaining(Consumer<? super E> action) {
                    i.forEachRemaining(action);
                }
            };
        }

        public List<E> subList(int fromIndex, int toIndex) {
            return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
        }

        /**
         * UnmodifiableRandomAccessList instances are serialized as
         * UnmodifiableList instances to allow them to be deserialized
         * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).
         * This method inverts the transformation.  As a beneficial
         * side-effect, it also grafts the RandomAccess marker onto
         * UnmodifiableList instances that were serialized in pre-1.4 JREs.
         *
         * Note: Unfortunately, UnmodifiableRandomAccessList instances
         * serialized in 1.4.1 and deserialized in 1.4 will become
         * UnmodifiableList instances, as this method was missing in 1.4.
         */
        private Object readResolve() {
            return (list instanceof RandomAccess
                    ? new UnmodifiableRandomAccessList<>(list)
                    : this);
        }
    }

        这里从UnmodifiableList的源码来分析:除了equals、hashCode、get、indexOf、lastIndexOf等方法外,其他方法都会抛出UnsupportedOperationException()异常,而这些方法的共同点都是返回该list的属性,说明UnmodifiableList是一个只读的集合,因此对这个List不能进行添加或删除元素等操作。

        如果需要将list转化为不可变的集合,Collections也提供了这样的方法,最终转化为UnmodifiableList。

  public static <T> List<T> unmodifiableList(List<? extends T> list) {
        return (list instanceof RandomAccess ?
                new UnmodifiableRandomAccessList<>(list) :
                new UnmodifiableList<>(list));
    }

        同样的 Collections 集合类中的 unmodifiableMap、unmodifiableSet也是只读内部类。它们可以在多线程环境下使用,或者在需要保护列表免受修改的场景下使用。文章来源地址https://www.toymoban.com/news/detail-831278.html

到了这里,关于java.lang.UnsupportedOperationException分析及解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • UnsupportedOperationException(不支持的操作异常)可能的原因和解决方法

    UnsupportedOperationException 表示尝试执行不支持的操作时抛出的异常。以下是可能导致此异常的一些常见原因和相应的解决方法: 使用不可变对象: 原因: 尝试在不可变对象上执行修改操作,例如在 Java 中对 String 对象调用修改方法。 解决方法: 确保你了解对象的不可变性。如

    2024年03月12日
    浏览(48)
  • 分析和解决java.lang.OutOfMemoryError: Java heap space问题

    最近客户反馈在生产环境导入操作时遇到任务一直执行中,并且入库的数据量一直不改变。通过日志查询,终于定位到报错信息如下: java.lang.OutOfMemoryError: Java heap space (JVM 堆空间溢出)简单来说就是在创建新的对象时, 堆内存中的空间不足以存放新创建的对象,导致此种问题

    2024年02月05日
    浏览(55)
  • java.lang.OutOfMemoryError: GC overhead limit exceeded问题分析及解决

    出现该问题的原因:当GC为释放很小空间占用大量时间时会抛出此异常,即(Sun 官方对此的定义,超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常)。一般是因为堆太小,导致异常的原因:没有足够的内存。 对于该项目我的启动命令如下:堆内存空间开辟的

    2024年01月21日
    浏览(52)
  • java: java.lang.ExceptionInInitializerError解决

    先理解一下这个报错的原因可能有: java.lang.ExceptionInInitializerError` 是一个错误,表示在初始化类时发生了异常。`com.sun.tools.javac.code.TypeTags` 是 Java 编译器中的一个类。 要解决此问题,您可以尝试以下几个步骤: 检查异常堆栈跟踪:查看完整的异常堆栈跟踪,找到具体的错误

    2024年02月13日
    浏览(32)
  • 已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!!已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!!

    已解决java.lang.NoClassDefFoundError异常的正确解决方法,亲测有效!!! java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError是Java虚拟机在运行时无法找到特定类的错误。 下滑查看解决方法 该错误通常发生在以下情况下: 编译时缺少依赖项:如果在开发过程中缺少所需的库或依赖项

    2024年02月14日
    浏览(54)
  • java.lang.NoSuchMethodError错误解决

    一、错误原因 java.lang.NoSuchMethodError错误可能的原因: 1、有这个类,该类没有这个方法; 2、类冲突、Jar包冲突、Jar包版本冲突; 3、有这个类(A),类中也有方法,但在B类中引用了A类,并调用A类的方法,后面修改A类,把该A类的方法返回值类型改变(如将方法返回类型由

    2024年02月04日
    浏览(40)
  • 已解决java.lang.ClassNotFoundException

    java.lang.ClassNotFoundException java.lang.ClassNotFoundException java.lang.ClassNotFoundException是一个Java异常,它表示在运行时找不到指定的类。 下滑查看解决方法 通常,这是由于类路径设置错误或缺失的依赖项引起的。要解决这个问题,可以尝试以下几个方法: 检查类路径:确保所需的类在

    2024年02月08日
    浏览(42)
  • 解决java.lang.NoClassDefFoundError错误

    在日常Java开发中,碰到java.lang.NoClassDefFoundError这样的错误,需要花费很多时间去找错误的原因,具体是哪个类不见了?类明明还在,为什么找不到?而且我们很容易把java.lang.NoClassDefFoundError和java.lang.ClassNotfoundException这两个错误搞混,事实上这两个错误是完全不同的。 我们往

    2024年02月11日
    浏览(40)
  • java.lang.NumberFormatException 如何解决

    java.lang.NumberFormatException 表示在将字符串转换为数值类型时发生了格式错误。这通常发生在使用像 Integer.parseInt(String) 、 Double.parseDouble(String) 等方法时,而提供的字符串不能正确解析为相应的数值类型。 以下是一些可能导致 NumberFormatException 的常见原因以及相应的解决方法:

    2024年04月15日
    浏览(37)
  • 已解决java.lang.UnsupportedClassVersionError

    已解决java.lang.UnsupportedClassVersionError java.lang.UnsupportedClassVersionError java.lang.UnsupportedClassVersionError是由于编译时使用的Java编译器版本和运行时使用的Java虚拟机版本不兼容导致的错误。 下滑查看解决方法 解决方法如下: 确认Java版本:首先确保你的Java开发环境(JDK)和Java运行环

    2024年02月05日
    浏览(111)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包