为什么由redis zset构建的HashSet保持排序?
why HashSet constructed from redis zset keeps sorted?
在Java中,HashSet是未排序的,如下所示:
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(4);
set.add(3);
set.add(2);
set.add(5);
set.forEach(e-> System.out.print(e+" "));
它的输出是:
1 2 3 4 5
当java集来自zset时,像这样:
redisTemplate.opsForZSet().add(key, 1, 0);
redisTemplate.opsForZSet().add(key, 4, 1);
redisTemplate.opsForZSet().add(key, 3, 2);
redisTemplate.opsForZSet().add(key, 2, 3);
redisTemplate.opsForZSet().add(key, 5, 4);
Set<Integer> set = redisTemplate.opsForZSet().range(key, 0, -1);
System.out.println(set.getClass());
set.forEach(e-> System.out.print(e+" "));
输出为:
java.util.HashSet
1 4 3 2 5
为什么此时输出保持输入的顺序?
ZSET是按分数排序的,不是ZSET中成员的key。所以在你的例子中:
redisTemplate.opsForZSet().add(key, 1, 0);
redisTemplate.opsForZSet().add(key, 4, 1);
redisTemplate.opsForZSet().add(key, 3, 2);
redisTemplate.opsForZSet().add(key, 2, 3);
redisTemplate.opsForZSet().add(key, 5, 4);
1
得分0
,5
得分4
。如果您将其更改为:
redisTemplate.opsForZSet().add(key, 1, 1);
redisTemplate.opsForZSet().add(key, 4, 4);
redisTemplate.opsForZSet().add(key, 3, 3);
redisTemplate.opsForZSet().add(key, 2, 2);
redisTemplate.opsForZSet().add(key, 5, 5);
你应该得到预期的结果。
jedis 不是 return 一个纯 hashSet,而是一个 LinkedHashSet,其中的元素是有序的。
package org.springframework.data.redis.serializer;
public abstract class SerializationUtils {
static <T extends Collection<?>> T deserializeValues(Collection<byte[]> rawValues, Class<T> type,
RedisSerializer<?> redisSerializer) {
// connection in pipeline/multi mode
if (rawValues == null) {
return null;
}
Collection<Object> values = (List.class.isAssignableFrom(type) ? new ArrayList<Object>(rawValues.size())
: new LinkedHashSet<Object>(rawValues.size()));
for (byte[] bs : rawValues) {
values.add(redisSerializer.deserialize(bs));
}
return (T) values;
}
}
在Java中,HashSet是未排序的,如下所示:
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(4);
set.add(3);
set.add(2);
set.add(5);
set.forEach(e-> System.out.print(e+" "));
它的输出是:
1 2 3 4 5
当java集来自zset时,像这样:
redisTemplate.opsForZSet().add(key, 1, 0);
redisTemplate.opsForZSet().add(key, 4, 1);
redisTemplate.opsForZSet().add(key, 3, 2);
redisTemplate.opsForZSet().add(key, 2, 3);
redisTemplate.opsForZSet().add(key, 5, 4);
Set<Integer> set = redisTemplate.opsForZSet().range(key, 0, -1);
System.out.println(set.getClass());
set.forEach(e-> System.out.print(e+" "));
输出为:
java.util.HashSet
1 4 3 2 5
为什么此时输出保持输入的顺序?
ZSET是按分数排序的,不是ZSET中成员的key。所以在你的例子中:
redisTemplate.opsForZSet().add(key, 1, 0);
redisTemplate.opsForZSet().add(key, 4, 1);
redisTemplate.opsForZSet().add(key, 3, 2);
redisTemplate.opsForZSet().add(key, 2, 3);
redisTemplate.opsForZSet().add(key, 5, 4);
1
得分0
,5
得分4
。如果您将其更改为:
redisTemplate.opsForZSet().add(key, 1, 1);
redisTemplate.opsForZSet().add(key, 4, 4);
redisTemplate.opsForZSet().add(key, 3, 3);
redisTemplate.opsForZSet().add(key, 2, 2);
redisTemplate.opsForZSet().add(key, 5, 5);
你应该得到预期的结果。
jedis 不是 return 一个纯 hashSet,而是一个 LinkedHashSet,其中的元素是有序的。
package org.springframework.data.redis.serializer;
public abstract class SerializationUtils {
static <T extends Collection<?>> T deserializeValues(Collection<byte[]> rawValues, Class<T> type,
RedisSerializer<?> redisSerializer) {
// connection in pipeline/multi mode
if (rawValues == null) {
return null;
}
Collection<Object> values = (List.class.isAssignableFrom(type) ? new ArrayList<Object>(rawValues.size())
: new LinkedHashSet<Object>(rawValues.size()));
for (byte[] bs : rawValues) {
values.add(redisSerializer.deserialize(bs));
}
return (T) values;
}
}