当前位置:首页 » 《随便一记》 » 正文

java.lang.UnsupportedOperationException分析及解决

13 人参与  2024年03月06日 08:26  分类 : 《随便一记》  评论

点击全文阅读


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

java.lang.UnsupportedOperationException: nullat 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也是只读内部类。它们可以在多线程环境下使用,或者在需要保护列表免受修改的场景下使用。


点击全文阅读


本文链接:http://zhangshiyu.com/post/74430.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 你活着,却死在我等你的第三年后续+番外_谨言佳佳温以宁全集_小说后续在线阅读_无删减免费完结_
  • 相思溺于夏时雨小说(裴景澈初念可)章节目录+起始篇章(相思溺于夏时雨)全章无套路在线
  • 未婚夫重生归来叫停手术,把剥开肚子的我困在手术台上40分钟(裴临渊阮离歌)
  • 完结文离婚是你提,净身出户你又哭什么精彩分享列表_完结文离婚是你提,净身出户你又哭什么精彩分享(苏铭余素伊)
  • 全书浏览哥哥重生救我,我带队灭了组织!(陈致远陈知韫)_哥哥重生救我,我带队灭了组织!(陈致远陈知韫)全书结局
  • 全文算命赚功德,我直接飞升成仙(楚天河林风)列表_全文算命赚功德,我直接飞升成仙
  • 八零丈夫抛妻弃子后悔不当初完整文本_顾尧全文_小说后续在线阅读_无删减免费完结_
  • 殉情三年,侯门主母休夫日百棺开道附加(殉情三年,侯门主母休夫日百棺开道)(沈宁鸢谢挽舟)全本浏览阅读连载中
  • 傅沉舟黎枝小说完整在线阅读(悲风诉尽离别)前传列表
  • 暗恋对象又坏又撩,她招架不住林雾贺景洲佚名
  • 溯光成伤尽余篇::结局+番外评价五颗星-裴砚舟温辞笙:结局+番外新上热文
  • 老公为养妹抽干孩子的血,我带他九十九个金丝雀集体改嫁列表_老公为养妹抽干孩子的血,我带他九十九个金丝雀集体改嫁(沈娇娇战淩赫)

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1