Java集合的视图和包装器、批操作以及集合与数组的转换

视图并非新构建集合,而是对原集合对象进行操作。

视图只是包装了接口,只能调用接口的方法。

1.轻量级集合包装器

  • 1)Arrays.asList 数组->视图对象(只能get/set,不能add/remove)
  • 2)Collections.nCopies对象只存储一次,不可修改
    Collections.singletonSet
    Collections.singletonList
    Collections.singletonMap
    ...

2.子范围

  • 1)List.subList可将任何操作应用于子范围(同步更新整个列表)
  • 2)SortedSet和NavigableSet,SortedMap和NavigableMap
    SortedSet.subSet(from, to) 返回的是半闭区间[)
    SortedSet.headSet(to)
    SortedSet.tailSet(from)
    NavigableSet.subSet headSet tailSet可控制边界是否包含
    SortedMap.subMap(from, to) 返回的是半闭区间[)
    SortedMap.headMap(to)
    SortedMap.tailMap(from)
    NavigableMap.subMap headMap tailMap可控制边界是否包含

3.不可修改的视图

不可修改视图对修改操作全部抛出异常,只能对其进行访问
Collections.unmodifiableCollection 其equals使用的Object
如下使用底层的equals:
Collections.unmodifiableList
Collections.unmodifiableSet
Collections.unmodifiableMap

以Collections.unmodifiableList为例:

    public static <T> List<T> unmodifiableList(List<? extends T> list) {
        return (list instanceof RandomAccess ?
                new UnmodifiableRandomAccessList<>(list) :
                new UnmodifiableList<>(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();
        }

4.同步视图

方法外面都包围了synchronized(mutex):
Collections.synchronizedCollection
Collections.synchronizedList
Collections.synchronizedSet
Collections.synchronizedMap

以Collections.synchronizedList为例:

    public static <T> List<T> synchronizedList(List<T> list) {
        return (list instanceof RandomAccess ?
                new SynchronizedRandomAccessList<>(list) :
                new SynchronizedList<>(list));
    }
    static class SynchronizedList<E>
        extends SynchronizedCollection<E>
        implements List<E> {
        private static final long serialVersionUID = -7754090372962971524L;

        final List<E> list;

        SynchronizedList(List<E> list) {
            super(list);
            this.list = list;
        }
        SynchronizedList(List<E> list, Object mutex) {
            super(list, mutex);
            this.list = list;
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            synchronized (mutex) {return list.equals(o);}
        }
        public int hashCode() {
            synchronized (mutex) {return list.hashCode();}
        }

        public E get(int index) {
            synchronized (mutex) {return list.get(index);}
        }
        public E set(int index, E element) {
            synchronized (mutex) {return list.set(index, element);}
        }
        public void add(int index, E element) {
            synchronized (mutex) {list.add(index, element);}
        }
        public E remove(int index) {
            synchronized (mutex) {return list.remove(index);}
        }

5.受查视图

用来对泛型类型发生问题提供调试支持,如果加入的类型不匹配,会抛出ClassCastException异常。
Collections.checkedCollection()
Collections.checkedList
Collections.checkedSet
Collections.checkedMap

以Collections.checkedList为例

    public static <E> List<E> checkedList(List<E> list, Class<E> type) {
        return (list instanceof RandomAccess ?
                new CheckedRandomAccessList<>(list, type) :
                new CheckedList<>(list, type));
    }
    static class CheckedList<E>
        extends CheckedCollection<E>
        implements List<E>
    {
        private static final long serialVersionUID = 65247728283967356L;
        final List<E> list;

        CheckedList(List<E> list, Class<E> type) {
            super(list, type);
            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 remove(int index)       { return list.remove(index); }
        public int indexOf(Object o)     { return list.indexOf(o); }
        public int lastIndexOf(Object o) { return list.lastIndexOf(o); }

        public E set(int index, E element) {
            return list.set(index, typeCheck(element));
        }

        public void add(int index, E element) {
            list.add(index, typeCheck(element));
        }
        @SuppressWarnings("unchecked")
        E typeCheck(Object o) {
            if (o != null && !type.isInstance(o))
                throw new ClassCastException(badElementMsg(o));
            return (E) o;
        }

6.集合框架本身的视图

Map有如下三个视图,这三个视图只能删除,不可添加:

  • Set<K> keySet()
    Collection<V> values()
    Set<Map.Entry<K, V>> entrySet()


如上图三个方法返回的KeySet Values EntrySet自身都没有add方法,该方法继承自AbstractCollection,抽象类中的add是抛出异常。

    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

7.批操作

  • Collection
    containsAll
    addAll
    removeAll
    retainAll
    clear
  • List
    addAll(i, elements)在指定位置批量插入

8.集合与数组之间的转换

  • 数组 -> 集合 Arrays.asList方法
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }


ArrayList重写了get和set,对于add和remove继承自AbstractList,这两个方法都是抛出异常:

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     *
     * <p>This implementation always throws an
     * {@code UnsupportedOperationException}.
     *
     * @throws UnsupportedOperationException {@inheritDoc}
     * @throws IndexOutOfBoundsException     {@inheritDoc}
     */
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
  • 集合 -> 数组 Collection中两个方法
Object[] toArray();

<T> T[] toArray(T[] a);

对于第二种toArray,支持泛型,保存了类型信息。若a足够大,直接填入,剩余填null;否则,分配新数组,类型与a相同。容量一致时,性能最好。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 集合框架体系概述 为什么出现集合类?方便多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方法. 数组...
    acc8226阅读 791评论 0 1
  • 四、集合框架 1:String类:字符串(重点) (1)多个字符组成的一个序列,叫字符串。生活中很多数据的描述都采...
    佘大将军阅读 775评论 0 2
  • Collection ├List │├LinkedList │├ArrayList │└Vector │└Stac...
    AndyZX阅读 893评论 0 1
  • 概述 Java集合框架由Java类库的一系列接口、抽象类以及具体实现类组成。我们这里所说的集合就是把一组对象组织到...
    absfree阅读 1,285评论 0 10
  • 桃花扇 文/青松 没什么商量 南风,总会把 写不清的惆怅 画成一树树桃花 剪刀样的二月 雷声过后 胸口还隐隐作痛 ...
    济南青松阅读 264评论 0 7