LRU是一種緩存淘汰算法,是一種緩存淘汰機(jī)制
具體原理不做贅述,這里只提供實(shí)現(xiàn)示例神年。
*目前只實(shí)現(xiàn)了Swift&OC版本,后續(xù)會(huì)更新雙鏈表等實(shí)現(xiàn)方法行嗤。
Swift代碼示例:
//
// LRUCache.swift
// LRU緩存工具類
// 本類只是實(shí)現(xiàn)LRU思路已日,并沒(méi)有進(jìn)行真正意義的本地緩存數(shù)據(jù)。具體采用什么方式進(jìn)行本地緩存栅屏,請(qǐng)自行添加飘千。
// Created by Miracle on 2022/4/15.
//
import UIKit
class LRUCache: NSObject {
static let shared = LRUCache()
// MARK: 私有屬性
/// 最大數(shù)量
private var maxCount: Int = 0
/// 存放key的數(shù)組
private var keysArr: [String] = [String]()
/// 存放數(shù)據(jù)的字典
private var dataDic: [String:Any] = [String:Any]()
// MARK: 公開方法
/// 創(chuàng)建/重置方法
/// - Parameter maxCount: 最大緩存數(shù)量
func initOrReset(maxCount: Int) {
//賦值最大緩存數(shù)量
self.maxCount = maxCount
//清空記錄的內(nèi)容
keysArr.removeAll()
dataDic.removeAll()
}
/// 增加數(shù)據(jù)緩存方法
/// - Parameters:
/// - value: 數(shù)據(jù)
/// - key: key
func add(value: Any, key: String) {
//是否已經(jīng)存在了
let isExist = keysArr.contains(key) && dataDic.keys.contains(key)
//存數(shù)據(jù)
dataDic[key] = value
//將key移動(dòng)到最前面
if isExist {
moveToHeader(key: key)
} else {
keysArr.insert(key, at: 0)
}
//超出最大緩存限制,刪除末位數(shù)據(jù)
if keysArr.count > maxCount {
let removeKey = keysArr.last ?? ""
remove(key: removeKey)
}
}
/// 根據(jù)key刪除緩存數(shù)據(jù)
func remove(key: String) {
//移除數(shù)據(jù)字典中的對(duì)應(yīng)數(shù)據(jù)
if dataDic.keys.contains(key) {
dataDic.removeValue(forKey: key)
}
//移除key數(shù)組中的key
if keysArr.contains(key) {
keysArr.removeAll(){
$0 == key
}
}
}
/// 根據(jù)key獲取數(shù)據(jù)
func getData(key: String) -> Any {
//根據(jù)key取數(shù)據(jù)
let data = dataDic[key] as Any
//將key移動(dòng)到最前面
moveToHeader(key: key)
return data
}
// MARK: 私有方法
/// 將key移動(dòng)到最前面
/// - Parameter key: 數(shù)據(jù)key
private func moveToHeader(key: String) {
//不包含直接返回
if !keysArr.contains(key) {
return
}
//移除對(duì)應(yīng)的key
keysArr.removeAll(){
$0 == key
}
//將key添加到第0個(gè)
keysArr.insert(key, at: 0)
}
}
OC代碼示例:
LRUCache-OC.h
//
// LRUCache-OC.h
// LRU緩存工具類
// 本類只是實(shí)現(xiàn)LRU思路栈雳,并沒(méi)有進(jìn)行真正意義的本地緩存數(shù)據(jù)护奈。具體采用什么方式進(jìn)行本地緩存,請(qǐng)自行添加哥纫。
// Created by Miracle on 2022/4/20.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LRUCache_OC : NSObject
+(instancetype)shard;
/// 創(chuàng)建/重置方法
/// @param maxCount 最大緩存數(shù)量
-(void)initOrResetWithMaxCount:(int)maxCount;
/// 添加緩存
-(void)addWithKey:(NSString *)key value:(id)value;
/// 根據(jù)key刪除數(shù)據(jù)
-(void)removeWithKey:(NSString *)key;
/// 根據(jù)key獲取數(shù)據(jù)
-(id)getDataWithKey:(NSString *)key;
@end
NS_ASSUME_NONNULL_END
LRUCache-OC.m
//
// LRUCache-OC.m
// LRU緩存工具類
// 本類只是實(shí)現(xiàn)LRU思路霉旗,并沒(méi)有進(jìn)行真正意義的本地緩存數(shù)據(jù)。具體采用什么方式進(jìn)行本地緩存,請(qǐng)自行添加厌秒。
// Created by Miracle on 2022/4/20.
//
#import "LRUCache-OC.h"
@interface LRUCache_OC()
/// 最大數(shù)量
@property(nonatomic,assign) int maxCount;
/// 存放key的數(shù)組
@property(nonatomic,strong) NSMutableArray * keysArr;
/// 存放數(shù)據(jù)的字典
@property(nonatomic,strong) NSMutableDictionary * dataDic;
@end
@implementation LRUCache_OC
+(instancetype)shard{
static LRUCache_OC * _shard;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_shard = [[[self class] alloc] init];
});
return _shard;
}
/// 創(chuàng)建/重置方法
/// @param maxCount 最大緩存數(shù)量
-(void)initOrResetWithMaxCount:(int)maxCount{
self.maxCount = maxCount;
self.keysArr = [[NSMutableArray alloc]initWithCapacity:0];
self.dataDic = [[NSMutableDictionary alloc]initWithCapacity:0];
}
/// 添加緩存
-(void)addWithKey:(NSString *)key value:(id)value{
//是否已經(jīng)存在了
BOOL isExist = [self.keysArr containsObject:key] && [self.dataDic.allKeys containsObject:key];
//存數(shù)據(jù)
[self.dataDic setValue:value forKey:key];
//將key移動(dòng)到最前面
if (isExist) {
[self moveToHeaderForKey:key];
} else {
[self.keysArr insertObject:key atIndex:0];
}
//超出最大限制读拆,刪除末位數(shù)據(jù)
if (self.keysArr.count > self.maxCount) {
NSString * lastKey = self.keysArr.lastObject;
[self removeWithKey:lastKey];
}
}
/// 將key移動(dòng)到最前面
-(void)moveToHeaderForKey:(NSString *)key{
//如果不包含,直接返回
if (![self.keysArr containsObject:key]) {
return;
}
[self.keysArr removeObject:key];
[self.keysArr insertObject:key atIndex:0];
}
/// 根據(jù)key刪除數(shù)據(jù)
-(void)removeWithKey:(NSString *)key{
if ([self.dataDic.allKeys containsObject:key]) {
[self.dataDic removeObjectForKey:key];
}
if ([self.keysArr containsObject:key]) {
[self.keysArr removeObject:key];
}
}
/// 根據(jù)key獲取數(shù)據(jù)
-(id)getDataWithKey:(NSString *)key{
id data = [self.dataDic objectForKey:key];
[self moveToHeaderForKey:key];
return data;
}
@end