LRU是一种缓存淘汰算法,是一种缓存淘汰机制
具体原理不做赘述,这里只提供实现示例。
*目前只实现了Swift&OC版本,后续会更新双链表等实现方法。
Swift代码示例:
//
// LRUCache.swift
// LRU缓存工具类
// 本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
// Created by Miracle on 2022/4/15.
//
import UIKit
class LRUCache: NSObject {
static let shared = LRUCache()
// MARK: 私有属性
/// 最大数量
private var maxCount: Int = 0
/// 存放key的数组
private var keysArr: [String] = [String]()
/// 存放数据的字典
private var dataDic: [String:Any] = [String:Any]()
// MARK: 公开方法
/// 创建/重置方法
/// - Parameter maxCount: 最大缓存数量
func initOrReset(maxCount: Int) {
//赋值最大缓存数量
self.maxCount = maxCount
//清空记录的内容
keysArr.removeAll()
dataDic.removeAll()
}
/// 增加数据缓存方法
/// - Parameters:
/// - value: 数据
/// - key: key
func add(value: Any, key: String) {
//是否已经存在了
let isExist = keysArr.contains(key) && dataDic.keys.contains(key)
//存数据
dataDic[key] = value
//将key移动到最前面
if isExist {
moveToHeader(key: key)
} else {
keysArr.insert(key, at: 0)
}
//超出最大缓存限制,删除末位数据
if keysArr.count > maxCount {
let removeKey = keysArr.last ?? ""
remove(key: removeKey)
}
}
/// 根据key删除缓存数据
func remove(key: String) {
//移除数据字典中的对应数据
if dataDic.keys.contains(key) {
dataDic.removeValue(forKey: key)
}
//移除key数组中的key
if keysArr.contains(key) {
keysArr.removeAll(){
$0 == key
}
}
}
/// 根据key获取数据
func getData(key: String) -> Any {
//根据key取数据
let data = dataDic[key] as Any
//将key移动到最前面
moveToHeader(key: key)
return data
}
// MARK: 私有方法
/// 将key移动到最前面
/// - Parameter key: 数据key
private func moveToHeader(key: String) {
//不包含直接返回
if !keysArr.contains(key) {
return
}
//移除对应的key
keysArr.removeAll(){
$0 == key
}
//将key添加到第0个
keysArr.insert(key, at: 0)
}
}
OC代码示例:
LRUCache-OC.h
//
// LRUCache-OC.h
// LRU缓存工具类
// 本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
// Created by Miracle on 2022/4/20.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface LRUCache_OC : NSObject
+(instancetype)shard;
/// 创建/重置方法
/// @param maxCount 最大缓存数量
-(void)initOrResetWithMaxCount:(int)maxCount;
/// 添加缓存
-(void)addWithKey:(NSString *)key value:(id)value;
/// 根据key删除数据
-(void)removeWithKey:(NSString *)key;
/// 根据key获取数据
-(id)getDataWithKey:(NSString *)key;
@end
NS_ASSUME_NONNULL_END
LRUCache-OC.m
//
// LRUCache-OC.m
// LRU缓存工具类
// 本类只是实现LRU思路,并没有进行真正意义的本地缓存数据。具体采用什么方式进行本地缓存,请自行添加。
// Created by Miracle on 2022/4/20.
//
#import "LRUCache-OC.h"
@interface LRUCache_OC()
/// 最大数量
@property(nonatomic,assign) int maxCount;
/// 存放key的数组
@property(nonatomic,strong) NSMutableArray * keysArr;
/// 存放数据的字典
@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;
}
/// 创建/重置方法
/// @param maxCount 最大缓存数量
-(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{
//是否已经存在了
BOOL isExist = [self.keysArr containsObject:key] && [self.dataDic.allKeys containsObject:key];
//存数据
[self.dataDic setValue:value forKey:key];
//将key移动到最前面
if (isExist) {
[self moveToHeaderForKey:key];
} else {
[self.keysArr insertObject:key atIndex:0];
}
//超出最大限制,删除末位数据
if (self.keysArr.count > self.maxCount) {
NSString * lastKey = self.keysArr.lastObject;
[self removeWithKey:lastKey];
}
}
/// 将key移动到最前面
-(void)moveToHeaderForKey:(NSString *)key{
//如果不包含,直接返回
if (![self.keysArr containsObject:key]) {
return;
}
[self.keysArr removeObject:key];
[self.keysArr insertObject:key atIndex:0];
}
/// 根据key删除数据
-(void)removeWithKey:(NSString *)key{
if ([self.dataDic.allKeys containsObject:key]) {
[self.dataDic removeObjectForKey:key];
}
if ([self.keysArr containsObject:key]) {
[self.keysArr removeObject:key];
}
}
/// 根据key获取数据
-(id)getDataWithKey:(NSString *)key{
id data = [self.dataDic objectForKey:key];
[self moveToHeaderForKey:key];
return data;
}
@end