Redis五种数据结构在JAVA中如何封装使用

目录
  • 数据结构
  • string字符串
    • string字符串简介
    • string字符串在Java中的封装
  • list列表
    • list列表简介
    • 队列
    • list列表在Java中的封装
  • hash(字典)
    • hash字典简介
    • hash字典在Java中的封装
  • set(集合)
    • set集合简介
    • set集合在Java中的封装
  • zset(有序列表)
    • zset有序列表
    • zset有序列表在Java中的封装

数据结构

Redis有五种基础数据结构,分别为:

1、string(字符串)

2、list(列表)

3、hash(字典)

4、set(集合)

5、zset(有序集合)

接下来我们就来具体看看每种数据结构的简介和常用指令,以及在JAVA中如何封装使用吧!

string字符串

string字符串简介

字符串的结构使用非常的广泛,常见的用途就是缓存用户信息。比如说博主的《杂货铺实战专栏》中的杂货铺项目,邮箱验证时生成的邮箱验证码等等。

我们将要存储的对象信息使用JSON序列化成字符串,然后将序列化后的字符串使用Redis进行缓存。在取存储信息的时候进行一次反序列化操作就可以了。

Redis的字符串与Java的字符串有所不同的就是,Java中的String是final类型的字符串,而Redis的字符串是动态字符串,是可以修改的字符串,内部实现结构类似于Java的ArrayList,采用预分配冗余空间来减少内存的频繁分配。

既Redis会分配比实际字符串大的capacity(空间),扩容的时候就扩容加倍现有的空间。但是字符串的最大长度为512MB。

一些普通的操作比如set、get、exists、del如下:

当然也可以通过mset、mget批量读写:

我们都知道,有些数据我们是不会让它长久存储在缓存里的,所以要设置对应的过期时间,可以通过expire、setex来设置,并且可以通过sexnx来判断key值是否存在不存在就创建:

当我们的value是一个整数的时候,还可以通过incr、decr、incrby、decrby进行增减操作,需要注意的是它的返回是介于signed long的最大值以及最小值之间的,一旦超出这个范围,就会报错:

string字符串在Java中的封装

(注:以下只列举string类型的工具类的完整写法,其他数据结构只列举部分写法)

在pom.xml引入依赖:

        <!-- redis依赖包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

你可以在yml文件中配置,或者在properties文件中配置,挑选一个你认为看着舒服的配置上就好:

# yml文件配置
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    jedis:
      pool:
        #连接池最大连接数(使用负值表示没有限制)
        max-active: 20
        #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1
        #连接池中的最大空闲连接
        max-idle: 20
        #连接池中的最小空闲连接
        min-idle: 2
    #连接超时时间(毫秒)
    timeout: 5000
# properties文件配置
#Redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#Redis数据库索引(默认为0)
spring.redis.database=0
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
#连接超时时间(毫秒)
spring.redis.timeout=5000

然后编写Redis的工具类:

package com.gantiexia.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author GanTieXia
 * @date 2021/11/21 18:07
 */

@Component
public class RedisUtils {

    /** 引入对应的依赖后注入即可*/
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public String get(final String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 写入缓存
     */
    public boolean set(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 带失效时间key
     *
     * @param key
     * @param value
     * @param timeOut
     * @param timeUnit
     * @return
     */
    public boolean setKeyTimeOut(final String key,String value,long timeOut,TimeUnit timeUnit){
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value, timeOut, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 更新缓存
     */
    public boolean getAndSet(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().getAndSet(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除缓存
     */
    public boolean delete(final String key) {
        boolean result = false;
        try {
            redisTemplate.delete(key);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

list列表

list列表简介

Redis的列表相当于Java语言中的LinkedList,但是它是链表,而不是数组。那么这就意味着它的插入和删除非常快,而索引定位却是比较慢的。

列表中的每个元素是使用双向指针连接起来的,支持向前遍历和向后遍历。当列表弹出最后一个元素时,该数据结构自动删除,内存被回收。

Redis的列表结构可以用来做异步队列使用。我们把需要延后处理的任务结构序列化成字符串,存入Redis列表,再启用另一个线程从列表中取得数据进行处理。

队列

众所周知,队列是先进先出的数据结构,可用于我们常听到的消息队列,可确保元素的访问顺序性。

栈是一种先进后出的数据结果,跟我们常用的撤回是一个道理。

还可以通过lindex查找对应位置上的元素,lrange 0 -1(-1代表最后一个元素,-2代表倒数第二个元素)获取所有的元素,ltrim可以保留某个区间的元素,砍掉其他位置的元素。但是这些操作的时间复杂度为O(n),所以一般都不推荐使用。

list列表在Java中的封装

(完整代码参考上文string的封装)

// 根据你的需要传入相应的参数
// set方法的主要语句
redisTemplate.opsForList(). ;  // .后面的方法根据你的应用场景写入

hash(字典)

hash字典简介

Redis的字典相当于JAVA语言里的HashMap,它是一个无需字典,内部存储了很多键值对。

而针对HashMap的概念模型,在博主的JAVA进阶篇——HashMap底层实现解析(一)一文中讲解得很清晰了。

不同的是,Redis的字典的值只能是字符串,并且他们的rehash也是不一样的。Java的HashMap在字典很大的时候,rehash是非常耗时的操作,得一次性全部rehash。而redis为了延续高性能,不产生堵塞,采用了渐进式的rehash策略。

渐进式rehash策略就是会在rehash的同时,保留新旧两个hash结构,查询时会同时查询两个hash结构,然后通过后续的定时任务以及hash操作指令中,将旧的hash结构转移到新的hash结构中,在最后一个hash元素搬移之后,旧hash结构删除,内存被回收。

hash的好处在哪呢,举个例子,当我们存储用户信息的时候,string是将整条信息直接序列化后存储,取出来以后还需要反序列化再获取我们想要的信息。使用hash则可以对用户结构中的每一个单一字段进行存储,比如我们要获取用户名的之后,就不用拿到一整条用户信息了,这样就可以节省网络流量。

但美中不足的是,hash结构的存储消耗要高于单个字符串。

接下来我们来看看操作:

hash字典在Java中的封装

(完整代码参考上文string的封装)

// 根据你的需要传入相应的参数
// set方法的主要语句
redisTemplate.opsForHash(). ;  // .后面的方法根据你的应用场景写入

set(集合)

set集合简介

Redis的集合相当于Java中的HashSet,内部的键值是无序的、唯一的,也就是在Java中我们所常用的使用Set去重。

Redis的集合内部相当于一个特殊的字典,字典中每一个key的键值value都是NULL,同其他数据结构一样,最后一个元素被移除时,数据结构删除,内存被回收。

接下来我们来看看操作指令:

set集合在Java中的封装

(完整代码参考上文string的封装)

// 根据你的需要传入相应的参数
// set方法的主要语句
redisTemplate.opsForSet(). ;  //.后面的方法根据你的应用场景写入

zset(有序列表)

zset有序列表

zset也是一个set,它保证了内部value的唯一性,并且给每一个value赋予一个score,代表value的排序权重。

zset可以用来干什么呢?比如粉丝列表,打开粉丝列表,value存储用户信息,score存储关注时间,粉丝列表就可以以关注时间排序展示…等等这里就不做过多的阐述了。

下面我们来看看操作:

zset有序列表在Java中的封装

(完整代码参考上文string的封装)

// 根据你的需要传入相应的参数
// set方法的主要语句
redisTemplate.opsForZSet(). ;  // .后面的方法根据你的应用场景写入

到此这篇关于Redis五种数据结构在JAVA中如何封装使用的文章就介绍到这了,更多相关Redis的内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 多维度深入分析Redis的5种基本数据结构

    目录 一.简介 二.string(字符串) 1.string(字符串)相关介绍 1.1 string(字符串)的内部结构 1.2 string(字符串)的扩容 2.string(字符串)的指令 2.1 单个键值对增删改查操作 2.2 批量键值对 2.3 过期set命令 2.4 不存在创建存在不更新 2.5计数 三.list(列表) 1.list(列表)相关介绍 1.1 list(列表)的内部结构 1.2 list(列表)的使用场景 2.list(列表)的指令 2.1 右进左出-队列 2.2 右进

  • Redis中5种数据结构的使用场景介绍

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 redis 中一共有5种数据结构,那每种数据结构的使用场景都是什么呢? String--字符串 Hash--字典 List--列表 Set--集合 Sorted Set--有序集合 下面我们就来简单说明一下它们各自的使用场景: 1. String--字符串 String 数据结构是简单的 key-

  • 浅谈redis五大数据结构和使用场景

    老规矩,先抛结论后验证 string:有点像java的hashMap,存的时候什么key,取的时候也什么key,常用于做缓存,保存用户信息.查询列表等: hash:这个有点像hashMap的value又套了个hashMap,下文有举例,一看就明白了: list:有序列表,类似Java的linkedList,可以在左边右边插入数据: set:去重集合,类似Java的hashset,可用于求交集,比如共同好友: zset:带权重的set集合,可用于做排行榜: 为了方便理解,我们基于这个dog类来做测

  • Redis五种数据结构在JAVA中如何封装使用

    目录 数据结构 string字符串 string字符串简介 string字符串在Java中的封装 list列表 list列表简介 队列 栈 list列表在Java中的封装 hash(字典) hash字典简介 hash字典在Java中的封装 set(集合) set集合简介 set集合在Java中的封装 zset(有序列表) zset有序列表 zset有序列表在Java中的封装 数据结构 Redis有五种基础数据结构,分别为: 1.string(字符串) 2.list(列表) 3.hash(字典)

  • java arrayList遍历的四种方法及Java中ArrayList类的用法

    java arrayList遍历的四种方法及Java中ArrayList类的用法 package com.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ArrayListDemo { public static void main(String args[]){ List<String> list = new ArrayList<String

  • 6种方法初始化JAVA中的list集合

    List 是 Java 开发中经常会使用的集合,你们知道有哪些方式可以初始化一个 List 吗?这其中不缺乏一些坑,今天栈长我给大家一一普及一下. 1.常规方式 List<String> languages = new ArrayList<>(); languages.add("Java"); languages.add("PHP"); languages.add("Python"); System.out.println

  • java 中的封装介绍及使用方法

    java 中的封装介绍及使用方法 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问. 要访问该类的代码和数据,必须通过严格的接口控制. 封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段. 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性. 封装的优点 1. 良好的封装能够减少耦合. 2. 类内部

  • Java中的封装、继承和多态,你真的都懂了吗

    封装 所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的成员变量和成员方法都使用private修饰了,我们现在来使用一下这个类. 当我们使用的时候编译器给出了下面这样的报错. 告诉我们说是private访问控制,那么这是什么意思呢?我们来看看另外一张图,那么这张图代表这什么呢?在看这张图之前,我们先来看看四者都提到的包,那么包又是什么呢,包可以简单理解为一个文件夹,把类放到放到包里面,也就相当于是专门的文件夹里面,这不是我们说的重点

  • 详解Java中的封装、继承、多态

    封装 在如何理解面向对象这篇文章中,提到所谓的封装就是"功能都给你做好了,你不必去理解它是怎么写出来的,直接使用即可.".但你得清楚一点,那就是这句话是相对于使用者来说的,而作为开发者,封装就得我们自己来干. 那么作为开发者,我们应该如何去封装呢?其实你应该反过来问,他们应该如何去使用,这样一想会简单很多,作为使用者,自然是希望越简单越好,也就是说,一些复杂的东西,我们不应该让使用者去操作,那也就是说我们应该把复杂的,以及不必要的参数给它封死,不让使用者去操作. 为什么不让使用者去操作

  • java中httpclient封装post请求和get的请求实例

    目录 httpclient封装post请求和get的请求 httpclient的post和get请求所用的代码 HttpClient发送Get.Post请求的实践 1. 配置及实例化HttpClient 2. 发送Get请求方法 3. 发送Post请求方法 4. 编写测试用例,进行Get .Post请求方法的测试 httpclient封装post请求和get的请求 在我们程序员生涯中,经常要复用代码,所以我们应该养成时常整理代码的好习惯,以下是我之前封装的 httpclient的post和get

  • Redis中五种数据类型简单操作

    Redis中五种数据类型简单操作 提出问题 Redis五种数据类型的简单增删改查命令??? 解决问题 假设你已经安装Redis服务器: 假设你已经打开Redis cli命令行工具: 假设你对Redis有所了解: Redis简单增删改查例子 例一:字符串的增删改查 #增加一个key为ay_key的值 127.0.0.1:6379> set ay_key "ay" OK #查询ay_key的值 127.0.0.1:6379> get ay_key "ay"

  • Java中List集合对象去重及按属性去重的8种方法

    最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大.基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华.所以我更想把java相关的基础知识进行穿针引线,进行整体上的总结. 总结java中创建并写文件的5种方式 总结java从文件中读取数据的6种方法 总结java创建文件夹的4种方法及其优缺点 总结java中删除文件或文件夹的7种方法 总结java中文件拷贝剪切的5种方式 比如之前我已经写了上面的这些内容,如果对java基

  • Java中的反射机制详解

    Java中的反射机制详解 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下

随机推荐