Java实现redis sortSet(zset)数据结构

  static class Tuple implements Comparable<Tuple> {
        private long uid;
        private long score;

        public long getUid() {
            return uid;
        }

        public Tuple setUid(long uid) {
            this.uid = uid;
            return this;
        }

        public long getScore() {
            return score;
        }

        public Tuple setScore(long score) {
            this.score = score;
            return this;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Tuple tuple = (Tuple) o;
            return Objects.equals(uid, tuple.uid);
        }

        @Override
        public int hashCode() {
            return Objects.hash(uid);
        }

        @Override
        public int compareTo(Tuple tuple) {
            return compare(this, tuple);
        }

        public static int compare(Tuple x, Tuple y) {
            return Comparator.nullsFirst(Comparator.comparing(Tuple::getScore).thenComparing(Tuple::getUid)).compare(x, y);
        }

    }

    public static Set<Tuple> concurrentSkipListSet = new ConcurrentSkipListSet<>();

    public static ConcurrentSkipListMap<Long, Tuple> concurrentSkipListMap = new ConcurrentSkipListMap<>();


    public static void main(String[] args) throws Exception {
        BiFunction<Long, Long, Long> function = (temUid, temScore) -> {
            //累加用户积分且返回累加后的积分
            return concurrentSkipListMap.compute(temUid, (temKey, oldValue) -> {
                Tuple tuple = Optional.ofNullable(oldValue).map(temTuple -> {
                    //移除跳表中的旧对象
                    concurrentSkipListSet.remove(temTuple);
                    //累加
                    return temTuple.setScore(temTuple.getScore() + temScore);
                }).orElseGet(() -> new Tuple().setUid(temUid).setScore(temScore));
                //添加到跳表
                concurrentSkipListSet.add(tuple);
                //返回计算结果
                return tuple;
            }).getScore();
        };
        //两个数据集合操作不是原子性的,所以只能单线程或者加同步锁实现 这里选择和redis一样的处理方案-单线程
        ExecutorService executorService = Executors.newWorkStealingPool(1);
        List<CompletableFuture<Void>> completableFutures = IntStream.rangeClosed(1, 9876).mapToObj(value -> CompletableFuture.runAsync(() -> function.apply(Long.valueOf(value % 10), Long.valueOf(1)), executorService)).collect(Collectors.toList());
        completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
        System.out.println(JSONObject.toJSONString(concurrentSkipListSet));
    }

执行结果:

[{
	"score":987,
	"uid":0
},{
	"score":987,
	"uid":7
},{
	"score":987,
	"uid":8
},{
	"score":987,
	"uid":9
},{
	"score":988,
	"uid":1
},{
	"score":988,
	"uid":2
},{
	"score":988,
	"uid":3
},{
	"score":988,
	"uid":4
},{
	"score":988,
	"uid":5
},{
	"score":988,
	"uid":6
}]
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值