redis 獲取 list 中的所有元素操作
一種方法是用 lrange( key, 0, -1 )。這種方法不會(huì)影響 redis list 中的數(shù)據(jù)。
List<String> list = jedis.lrange( key, 0, -1 );
另一種方法是用 while + lpop 。這種方法會(huì)將 redis list 中的數(shù)據(jù)都彈出來,redis list 就變成空的了。
List<String> list = new ArrayList<>();
String st = jedis.lpop( key );
while ( st != null ) {
list.add( st );
st = jedis.lpop( key );
}
這兩種方法獲得的 List<String> list 中的元素的順序是一樣的。
補(bǔ)充:redis列表類型list如何一次返回多個(gè)值并刪除這些值
redis的列表類型list是一個(gè)常用的數(shù)據(jù)類型,但是這個(gè)類型并不支持一次性返回多個(gè)值并刪除這些已經(jīng)返回的值。
其實(shí)我們可以通過redis的事務(wù),來完成這個(gè)一次性返回多個(gè)值并刪除這些已經(jīng)返回的值的需求。
redis中的事務(wù)就是一組命令的集合,這些命令要么全部執(zhí)行,要么全都不執(zhí)行。redis事務(wù)的原理就是一次性將命令都發(fā)給服務(wù)端,
當(dāng)服務(wù)接收到exec命令之后,按照事務(wù)中命令的順序依次執(zhí)行事務(wù)中的命令。exec命令的返回值就是事務(wù)中依次執(zhí)行的命令返回值的集合,返回值的順序和命令的執(zhí)行順序相同。如果在發(fā)送exec命令前,客戶端和服務(wù)端失去連接,這時(shí)redis會(huì)清空這個(gè)事務(wù)隊(duì)列。
介紹完這些原理,我們?cè)賮砜纯慈绾瓮瓿梢淮涡苑祷囟鄠€(gè)值并刪除這些已經(jīng)返回的值的需求。
我們這里要利用兩個(gè)列表類型的命令:lrange和ltrim
lrange key start end // 從左邊依次返回key的[start,end] 的所有值,注意返回結(jié)果包含兩端的值。
ltrim key start end //刪除指定索引之外的所有元素,注意刪除之后保留的元素包含兩端的start和end索引值。
我們這里舉例測(cè)試:

我們構(gòu)造了一個(gè)名為yujie_list的列表類型數(shù)據(jù)結(jié)構(gòu),從左邊依次壓入:0 1 2 3 4 5 6 7 8 9
最后從左到右依次列出列表中的所有元素如上圖所示。
接下來我們測(cè)試lrange和ltrim命令如下圖:

我們使用lrange yujie_list 0 3命令,從左到右依次列出從索引0到索引3的元素,注意包含了索引0 值為9和索引3值為6的元素。
我們使用ltrim yujie_list 4 -1命令,刪除索引4到最右端之外的所有元素,注意刪除的元素不包含索引4職位5的元素。
好了原理講完了,接下來我們上代碼:
RedisUtil是一個(gè)工具類,用于連接redis服務(wù)端。
/**
* 連接redis服務(wù)的工具類
* @author yujie.wang3
*
*/
public final class RedisUtil {
//Redis服務(wù)器IP
private static String ADDR = "10.4.36.93";
//Redis的端口號(hào)
private static int PORT = 6379;
//可用連接實(shí)例的最大數(shù)目,默認(rèn)值為8;
//如果賦值為-1,則表示不限制;如果pool已經(jīng)分配了maxActive個(gè)jedis實(shí)例,則此時(shí)pool的狀態(tài)為exhausted(耗盡)。
private static int MAX_ACTIVE = 100;
//控制一個(gè)pool最多有多少個(gè)狀態(tài)為idle(空閑的)的jedis實(shí)例,默認(rèn)值也是8。
private static int MAX_IDLE = 20;
//等待可用連接的最大時(shí)間,單位毫秒,默認(rèn)值為-1,表示永不超時(shí)。如果超過等待時(shí)間,則直接拋出JedisConnectionException;
private static int MAX_WAIT = 10000;
private static int TIMEOUT = 10000;
//在borrow一個(gè)jedis實(shí)例時(shí),是否提前進(jìn)行validate操作;如果為true,則得到的jedis實(shí)例均是可用的;
private static boolean TEST_ON_BORROW = true;
private static JedisPool jedisPool = null;
/**
* 初始化Redis連接池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxActive(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWait(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取Jedis實(shí)例
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 釋放jedis資源
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
}
測(cè)試類如下:
/**
* 一次返回多個(gè)列表值并刪除返回值測(cè)試類
* @author yujie.wang
*
*/
public class RedisTest {
public static void main(String[] args) {
String key = "yujie_test_list";
initList(key,9);
printList(key,"原始列表數(shù)據(jù)");
List<String> listResult = getListMultValueAfterDel(key,0,3);
System.out.println("一次返回并刪除數(shù)據(jù):"+listResult.toString());
printList(key,"刪除之后列表數(shù)據(jù)");
}
public static void initList(String key,int maxValue){
Jedis client = RedisUtil.getJedis();
for(int i = 0;i <= maxValue; i++){
client.lpush(key, String.valueOf(i));
}
System.out.println("初始化列表:"+ key + "完畢");
}
public static void printList(String key,String message){
Jedis client = RedisUtil.getJedis();
List<String> list = client.lrange(key, 0, -1);
System.out.println(message+ " : " + list.toString());
}
@SuppressWarnings("unchecked")
public static List<String> getListMultValueAfterDel(String key,int start, int end){
List<Object> list = null;
List<String> listStr = new ArrayList<String>();
try {
Jedis jedis = RedisUtil.getJedis();
Transaction ts = jedis.multi();
ts.lrange(key, start, end);
ts.ltrim(key, end+1, -1);
list = ts.exec();
RedisUtil.returnResource(jedis);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
if(list != null && !list.isEmpty()){
try {
//獲得命令lrange(key, start, end)的返回結(jié)果
listStr = (ArrayList<String>)list.get(0);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
} else {
return Collections.emptyList();
}
return listStr;
}
}
輸出結(jié)果:

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn)
MyBatis可以通過定義多個(gè)表的關(guān)聯(lián)關(guān)系,實(shí)現(xiàn)多表查詢,本文主要介紹了MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
SpringBoot Starter機(jī)制及整合tomcat的實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringBoot Starter機(jī)制及整合tomcat的實(shí)現(xiàn),我們知道SpringBoot自己在“后臺(tái)”幫我們配置了很多原本需要我們手動(dòng)去的東西,至于這個(gè)“后臺(tái)”是啥,就是Starter機(jī)制2022-09-09
java實(shí)現(xiàn)多個(gè)文件壓縮成壓縮包
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多個(gè)文件壓縮成壓縮包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
詳解Java線程池如何實(shí)現(xiàn)優(yōu)雅退出
這篇文章我們將從源碼角度深度解析線程池是如何優(yōu)雅的退出程序的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)java線程池有一定幫助,需要的可以參考一下2022-07-07
Java超詳細(xì)講解如何生成隨機(jī)整數(shù)
在?Java?中,生成隨機(jī)數(shù)的場(chǎng)景有很多,所以本文我們就來盤點(diǎn)一下?幾種生成隨機(jī)數(shù)的方式,以及它們之間的區(qū)別和每種生成方式所對(duì)應(yīng)的場(chǎng)景2022-05-05

