DefaultHashOperations multiget的一个坑

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: DefaultHashOperations的multiget如果没有数据会返回java.util.Collections.EmptyList,这个List没有重写add方法。   List resultIds=redisTemplate.

 

DefaultHashOperations的multiget如果没有数据会返回java.util.Collections.EmptyList,这个List没有重写add方法。

 

List<Long> resultIds=redisTemplate.boundHashOps(“key”).multiGet(ids)

 

resultIds在add一个新元素时,报了一下的错:
java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:148)
        at java.util.AbstractList.add(AbstractList.java:108)

 

原因:

org.springframework.data.redis.core.RedisTemplate#boundHashOps

    public List<HV> multiGet(Collection<HK> hashKeys) {
        return ops.multiGet(getKey(), hashKeys);
    }

org.springframework.data.redis.core.DefaultHashOperations#multiGet

    public List<HV> multiGet(K key, Collection<HK> fields) {
        if (fields.isEmpty()) {
            return Collections.emptyList();//这个list是java.util.Collections#emptyList中的java.util.Collections.EmptyList
        }

        final byte[] rawKey = rawKey(key);

        final byte[][] rawHashKeys = new byte[fields.size()][];

        int counter = 0;
        for (HK hashKey : fields) {
            rawHashKeys[counter++] = rawHashKey(hashKey);
        }

        List<byte[]> rawValues = execute(new RedisCallback<List<byte[]>>() {

            public List<byte[]> doInRedis(RedisConnection connection) {
                return connection.hMGet(rawKey, rawHashKeys);
            }
        }, true);

        return deserializeHashValues(rawValues);
    }

 

这个java.util.Collections.EmptyList没有重写add方法:

    private static class EmptyList<E>
        extends AbstractList<E>
        implements RandomAccess, Serializable {
        private static final long serialVersionUID = 8842843931221139166L;

        public Iterator<E> iterator() {
            return emptyIterator();
        }
        public ListIterator<E> listIterator() {
            return emptyListIterator();
        }

        public int size() {return 0;}
        public boolean isEmpty() {return true;}

        public boolean contains(Object obj) {return false;}
        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }

        public Object[] toArray() { return new Object[0]; }

        public <T> T[] toArray(T[] a) {
            if (a.length > 0)
                a[0] = null;
            return a;
        }

        public E get(int index) {
            throw new IndexOutOfBoundsException("Index: "+index);
        }

        public boolean equals(Object o) {
            return (o instanceof List) && ((List<?>)o).isEmpty();
        }

        public int hashCode() { return 1; }

        @Override
        public boolean removeIf(Predicate<? super E> filter) {
            Objects.requireNonNull(filter);
            return false;
        }
        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(operator);
        }
        @Override
        public void sort(Comparator<? super E> c) {
        }

        // Override default methods in Collection
        @Override
        public void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
        }

        @Override
        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }

        // Preserves singleton property
        private Object readResolve() {
            return EMPTY_LIST;
        }
    }

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
5月前
|
Java 容器 Spring
DefaultListableBeanFactory
DefaultListableBeanFactory 是一个完整的、功能成熟的 IoC 容器,如果你的需求很简单,甚至可以直接使用 DefaultListableBeanFactory,如果你的需求比较复杂,那么通过扩展 DefaultListableBeanFactory 的功能也可以达到,可以说 DefaultListableBeanFactory 是整个 Spring IoC 容器的始祖。
|
4月前
|
计算机视觉
detectMultiScale
【6月更文挑战第8天】
153 4
|
开发工具 Python
ignatureNonceIsNull
ignatureNonceIsNull
69 1
|
Serverless 程序员 云计算
Serverful
Serverful
175 0
Helpful Maths
Helpful Maths
134 0
Helpful Maths
|
Web App开发 前端开发 JavaScript
gulp
gulp 1. 安装 npm install --g gulp 2. 初始化 npm init 3.
1086 0