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

  這兩個類可能不少人都不會在乎,由於咱們平時都是使用的java.util.ArrayList,可是正是由於這樣,有的時候你可能會遇到 java.lang.UnsupportedOperationException這樣的問題,說實話,第一次遇到這種異常我也是一臉矇蔽的,之前基本不會遇到這種問題。說一下我遇到的場景吧。由於業務須要,我須要在多個list中找出他們交集,而後放到一個新的list中,當時第一想法是,這還不簡單,寫一個通用方法,參數是List<List<Integer>> list這種形式,而後循環這個list,經過retainAll()方法取交集就行了。這種方法網上確定有現成的,嗯,搜了一下果真有,那我就不客氣了。果斷複製粘貼。可是實際運行的時候卻報錯。當時真的是無語的要死。仍是直接貼代碼吧。java

/**
     * 從 有值的 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()方法。既然知道問題出在哪裏了,那麼問題就好解決了。這裏附上正確的代碼吧。spa

/**
     * 從 有值的 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而已,通過測試,是可行且正確的。code

由於以前我也沒有在乎Arrays這個類裏面還有一個內部ArrayList類,因此第一次遇到這個問題仍是花了一點時間來解決這個問題的。這裏記錄一下這個問題。對象

相關文章
相關標籤/搜索