Collections的singleton,singletonList,singletonMap

栏目: IT技术 · 发布时间: 5年前

内容简介:今天记录一下在IDEA的这里只需要创建一个元素的PS:创建出来的都是

今天记录一下在IDEA的 sonarLint 插件代码分析提示需要优化的代码:

//converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));
converter.setSupportedMediaTypes(Collections.singletonList(new MediaType("application", "json", StandardCharsets.UTF_8)));

这里只需要创建一个元素的 List 的时候用 Arrays.asList() 的话那插件就会在代码下报黄线提示你这是代码坏味道,建议优化。后面我就发现了使用 Collectionssingleton 的一系列方法创建单个元素集合使用:

Set<T> singleton(T o)
List<T> singletonList(T o)
Map<K, V> singletonMap(K key, V value)

PS:创建出来的都是

singleton

源码片段:

/**
     * Returns an immutable set containing only the specified object.
     * 返回仅包含指定对象的不可变集合。
     * The returned set is serializable.
     * 返回的集合是可序列化的。
     *
     * @param  <T> the class of the objects in the set
     * @param <T>集合中对象的类
     * @param o the sole object to be stored in the returned set.
     * @param o唯一要存储在返回集中的对象。
     * @return an immutable set containing only the specified object.
     * @返回一个仅包含指定对象的不可变集合。
     */
    public static <T> Set<T> singleton(T o) {
        return new SingletonSet<>(o);
    }

 /**
     * @serial include
     * @序列包括
     */
    private static class SingletonSet<E>
        extends AbstractSet<E>
        implements Serializable
    {
        private static final long serialVersionUID = 3193687207550431679L;

        private final E element;

        SingletonSet(E e) {element = e;}

        public Iterator<E> iterator() {
            return singletonIterator(element);
        }

        public int size() {return 1;}

        public boolean contains(Object o) {return eq(o, element);}

        // Override default methods for Collection
        //覆盖Collection的默认方法
        @Override
        public void forEach(Consumer<? super E> action) {
            action.accept(element);
        }
        @Override
        public Spliterator<E> spliterator() {
            return singletonSpliterator(element);
        }
        @Override
        public boolean removeIf(Predicate<? super E> filter) {
            throw new UnsupportedOperationException();
        }
    }

源码注释可以看到 Returns an immutable set containing only the specified object. (返回仅包含指定对象的不可变集合。),可以说明这个方法返回的 Set 集合是不可变的,要是对其进行任何更改操作将会导致报出 throw new UnsupportedOperationException(); 错误。

singletonList

这是最简单并且推荐的方法,可以在其中 创建不可变 List 的单个元素 。用这个方法创建的列表也是 不可变 的,所以你确定在任何情况下列表中不会有更多的元素。

Collections.singletonList() 返回的 List 的容量始终是为** 1 **,要是对其进行任何更改操作也将会导致报出 UnsupportedOperationException 错误

源码片段:

/**
     * Returns an immutable list containing only the specified object.
     * 返回仅包含指定对象的不可变列表。
     * The returned list is serializable.
     * 返回的列表是可序列化的。
     *
     * @param  <T> the class of the objects in the list
     * @param <T>列表中对象的类
     * @param o the sole object to be stored in the returned list.
     * @param是要存储在返回列表中的唯一对象。
     * @return an immutable list containing only the specified object.
     * @返回一个仅包含指定对象的不可变列表。
     * @since 1.3
     * @从1.3开始
     */
    public static <T> List<T> singletonList(T o) {
        return new SingletonList<>(o);
    }

/**
     * @serial include
     * @序列包括
     */
    private static class SingletonList<E>
        extends AbstractList<E>
        implements RandomAccess, Serializable {

        private static final long serialVersionUID = 3093736618740652951L;

        private final E element;

        SingletonList(E obj)                {element = obj;}

        public Iterator<E> iterator() {
            return singletonIterator(element);
        }

        public int size()                   {return 1;}

        public boolean contains(Object obj) {return eq(obj, element);}

        public E get(int index) {
            if (index != 0)
              throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
            return element;
        }

        // Override default methods for Collection
        //覆盖Collection的默认方法
        @Override
        public void forEach(Consumer<? super E> action) {
            action.accept(element);
        }
        @Override
        public boolean removeIf(Predicate<? super E> filter) {
            throw new UnsupportedOperationException();
        }
        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            throw new UnsupportedOperationException();
        }
        @Override
        public void sort(Comparator<? super E> c) {
        }
        @Override
        public Spliterator<E> spliterator() {
            return singletonSpliterator(element);
        }
    }

PS: Array.asList() 此方法也是快速创建 List ,创建出来的列表是 可变 的。

singletonMap

Collections.singletonMap(key, value)

Map<KeyType, ValueType> map = new HashMap<KeyType, ValueType>();
map.put(key, value);

当你只有一个键/值对时,使用 singletonMap 更好,减少了不少代码。

划重点: 只有一个键/值对时

源码片段:

/**
     * Returns an immutable map, mapping only the specified key to the
     * 返回一个不可变的映射,只将指定的键映射到
     * specified value.  The returned map is serializable.
     * 指定值返回的映射是可序列化的。
     *
     * @param <K> the class of the map keys
     * @param <K>映射键的类
     * @param <V> the class of the map values
     * @param <V>map值的类别
     * @param key the sole key to be stored in the returned map.
     * @param键是要存储在返回地图中的唯一键。
     * @param value the value to which the returned map maps <tt>key</tt>.
     * @param value是返回的地图将key映射到的值。
     * @return an immutable map containing only the specified key-value mapping.
     * 返回一个只包含指定键-值映射的不可变映射。
     * @since 1.3
     * @从1.3开始
     */
    public static <K,V> Map<K,V> singletonMap(K key, V value) {
        return new SingletonMap<>(key, value);
    }

/**
     * @serial include
     * @序列包括
     */
    private static class SingletonMap<K,V>
          extends AbstractMap<K,V>
          implements Serializable {
        private static final long serialVersionUID = -6979724477215052911L;

        private final K k;
        private final V v;

        SingletonMap(K key, V value) {
            k = key;
            v = value;
        }

        public int size()                                           {return 1;}
        public boolean isEmpty()                                {return false;}
        public boolean containsKey(Object key)             {return eq(key, k);}
        public boolean containsValue(Object value)       {return eq(value, v);}
        public V get(Object key)              {return (eq(key, k) ? v : null);}

        private transient Set<K> keySet;
        private transient Set<Map.Entry<K,V>> entrySet;
        private transient Collection<V> values;

        public Set<K> keySet() {
            if (keySet==null)
                keySet = singleton(k);
            return keySet;
        }

        public Set<Map.Entry<K,V>> entrySet() {
            if (entrySet==null)
                entrySet = Collections.<Map.Entry<K,V>>singleton(
                    new SimpleImmutableEntry<>(k, v));
            return entrySet;
        }

        public Collection<V> values() {
            if (values==null)
                values = singleton(v);
            return values;
        }

        // Override default methods in Map
        // 覆盖Map中的默认方法
        @Override
        public V getOrDefault(Object key, V defaultValue) {
            return eq(key, k) ? v : defaultValue;
        }

        @Override
        public void forEach(BiConsumer<? super K, ? super V> action) {
            action.accept(k, v);
        }

        @Override
        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V putIfAbsent(K key, V value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean remove(Object key, Object value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean replace(K key, V oldValue, V newValue) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V replace(K key, V value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V computeIfAbsent(K key,
                Function<? super K, ? extends V> mappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V computeIfPresent(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V compute(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V merge(K key, V value,
                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }
    }

这三个内部类都是非常高效的

  • SingletonListSingletonSet 都用一个属性来表示拥有的元素,而不是用数组、列表来表示, SingletonMap 分别用两个属性表示 key/value ,内存使用上更高效
  • 在方法的实现上也更高效,减少了循环。比如 size 方法都是直接返回 1 , List.contains 方法是把参数与属性元素直接对比。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code Reading

Code Reading

Diomidis Spinellis / Addison-Wesley Professional / 2003-06-06 / USD 64.99

This book is a unique and essential reference that focuses upon the reading and comprehension of existing software code. While code reading is an important task faced by the vast majority of students,......一起来看看 《Code Reading》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具