前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Collections的singleton,singletonList,singletonMap

Collections的singleton,singletonList,singletonMap

作者头像
爱敲代码的猫
发布2020-07-14 16:58:44
1.1K0
发布2020-07-14 16:58:44
举报
文章被收录于专栏:爱敲代码的猫爱敲代码的猫

Collections的singleton,singletonList,singletonMap

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

代码语言:javascript
复制
//converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));
converter.setSupportedMediaTypes(Collections.singletonList(new MediaType("application", "json", StandardCharsets.UTF_8)));

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

  • 创建一个元素的Set:Set<T> singleton(T o)
  • 创建一个元素的List:List<T> singletonList(T o)
  • 创建一个元素的Map:Map<K, V> singletonMap(K key, V value)

PS:创建出来的都是

singleton

源码片段:

代码语言:javascript
复制
/**
     * 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错误

源码片段:

代码语言:javascript
复制
/**
     * 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

代码语言:javascript
复制
Collections.singletonMap(key, value)

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

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

源码片段:

代码语言:javascript
复制
/**
     * 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 方法是把参数与属性元素直接对比。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱敲代码的猫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Collections的singleton,singletonList,singletonMap
    • singleton
      • singletonList
        • singletonMap
        相关产品与服务
        腾讯云代码分析
        腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档