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

java.lang.UnsupportedOperationException分析及解决

12 人参与  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)
  • 赞助本站

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

最新文章

  • 繁花盛意难平全书+后续+结局(陆依霜轩辕翊)全书列表_繁花盛意难平(陆依霜轩辕翊)繁花盛意难平全书+后续+结局在线
  • 全球灾变:我有一座恐怖屋全文免费在线阅读_[钟无咎林澜]全文免费无弹窗阅读_笔趣阁
  • 「乖巧面具撕碎那天,全网求我别黑化」章节多结局预体验‌_宋且微萧淮无弹窗阅读
  • (番外)+(全书)日暮青山绿渐隐全书+后续+结局(日暮青山绿渐隐全书+后续+结局)_许星森纪冰雪列表_笔趣阁(日暮青山绿渐隐全书+后续+结局)
  • [我预见了所有悲剧,除了爱]最新章节在线阅读_「白月光」小说无删减版在线免费阅读
  • (番外)+(全书)爱若有天意,兜转终可回全书+后续+结局(宋清澜萧沉)_爱若有天意,兜转终可回全书+后续+结局列表_笔趣阁(爱若有天意,兜转终可回全书+后续+结局)
  • [繁花盛意难平]小说节选推荐_陆依霜轩辕翊陆青仪节选推荐
  • [纵她追悔,爱已成荒芜]小说精彩节选推荐_「苏萌林澈白月光」小说精彩节选试读
  • [老婆让我别拦着她嫁豪门]小说节选免费试读_[屈英哲韩海雪温文尔雅]精彩章节分享
  • 青梅诱人竹马男主轻点宠(许嘉易顾思瑜)全书浏览_青梅诱人竹马男主轻点宠全书浏览
  • 阮雾梨闻砚辞人面桃花长相忆结局+番外(阮雾梨闻砚辞)_人面桃花长相忆结局+番外阮雾梨闻砚辞列表_笔趣阁(阮雾梨闻砚辞)
  • 人面桃花长相忆闻砚辞结局+番外+续集(阮雾梨闻砚辞)结局_(阮雾梨闻砚辞人面桃花长相忆闻砚辞结局+番外+续集全书结局)结局(阮雾梨闻砚辞)

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

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