java.util.ArrayList和java.util.Arrays.ArrayList

  这两个类可能很多人都不会在意,因为我们平时都是使用的java.util.ArrayList,但是正是因为这样,有的时候你可能会遇到 java.lang.UnsupportedOperationException这样的问题,说实话,第一次遇到这种异常我也是一脸蒙蔽的,以前基本不会遇到这种问题。说一下我遇到的场景吧。因为业务需要,我需要在多个list中找出他们交集,然后放到一个新的list中,当时第一想法是,这还不简单,写一个通用方法,参数是List<List<Integer>> list这种形式,然后循环这个list,通过retainAll()方法取交集就好了。这种方法网上肯定有现成的,嗯,搜了一下果然有,那我就不客气了。果断复制粘贴。但是实际运行的时候却报错。当时真的是无语的要死。还是直接贴代码吧。

/**
     * 从 有值的 list 里取交集
     * @param lists
     * @return
     */
    public List<Integer> intersection(List<List<Integer>> lists) {
        if(lists == null || lists.size() == 0){
            return null;
        }
        ArrayList<List<Integer>> arrayList = new ArrayList<>(lists);
        for (int i = 0; i < arrayList.size(); i++) {
            List<Integer> list = arrayList.get(i);
            // 去除空集合
            if (list == null || list.size() == 0) {
                arrayList.remove(list);
                i-- ;
            }
        }
        if(arrayList.size() == 0){
            return null;
        }
        List<Integer> intersection = arrayList.get(0);
        // 就只有一个非空集合,结果就是他
        if(arrayList.size() == 1) {
            return intersection;
        }
        // 有多个非空集合,直接挨个交集
        //这里之前写的i < arrayList.size() -1
        for (int i = 1; i < arrayList.size(); i++) {
            intersection.retainAll(arrayList.get(i));
        }
        return intersection;
    }
public List<Integer> retainElementList(List<List<Integer>> elementLists) {

        Optional<List<Integer>> result = elementLists.parallelStream()
                .filter(elementList -> elementList != null && ((List) elementList).size() != 0)
                .reduce((a, b) -> {
                    a.retainAll(b);
                    return a;
                });
        return result.orElse(new ArrayList<>());
    }

就是拷的这两个,第一个方法for循环那里条件还写错了,当时我解决了报错之后运行发现还是不对,真的是气死了,我这么相信你们,大佬们你们博客的这些代码真的自己测试过么,,,,还是说主要的问题吧。这两个方法跑起来肯定是报错的。那么问题出在哪里呢?先看第一个方法,

List<Integer> intersection = arrayList.get(0);
System.out.println(intersection.getClass().getName()); intersection.retainAll(arrayList.get(i));

就是这里了,我们输出intersection这个对象的类型。发现他是java.util.Arrays.ArrayList这个类。而这个类是没有retainAll()这个方法的。我们需要使用java.util.ArrayList这个类来使用retainAll()方法。既然知道问题出在哪里了,那么问题就好解决了。这里附上正确的代码吧。

/**
     * 从 有值的 list 里取交集
     * @param lists
     * @return
     */
    public List<Integer> intersection(List<List<Integer>> lists) {
        if(lists == null || lists.size() == 0){
            return null;
        }
        ArrayList<List<Integer>> arrayList = new ArrayList<>(lists);
        for (int i = 0; i < arrayList.size(); i++) {
            List<Integer> list = arrayList.get(i);
            // 去除空集合
            if (list == null || list.size() == 0) {
                arrayList.remove(list);
                i-- ;
            }
        }
        if(arrayList.size() == 0){
            return null;
        }
        List<Integer> intersection = new ArrayList<>(arrayList.get(0));
        // 就只有一个非空集合,结果就是他
        if(arrayList.size() == 1) {
            return intersection;
        }
        // 有多个非空集合,直接挨个交集
        for (int i = 1; i < arrayList.size(); i++) {
            intersection.retainAll(arrayList.get(i));
        }
        return intersection;
    }
public List<Integer> retainElementList(List<List<Integer>> elementLists) {

        Optional<List<Integer>> result = elementLists.parallelStream()
                .filter(elementList -> elementList != null && ((List) elementList).size() != 0)
                .reduce((a, b) -> {
                    a = new ArrayList<>(a);
                    a.retainAll(b);
                    return a;
                });
        return result.orElse(new ArrayList<>());
    }

可以看出,两个代码并没有什么改动,只是将调用retainAll()方法的对象转化为了java.util.ArrayList而已,经过测试,是可行且正确的。

因为之前我也没有在意Arrays这个类里面还有一个内部ArrayList类,所以第一次遇到这个问题还是花了一点时间来解决这个问题的。这里记录一下这个问题。


 
posted @ 2018-11-22 11:22  徐世龙  阅读(1127)  评论(0编辑  收藏  举报