LiveData原理解析和仿写一个LiveDataBus

2024-02-17 17:08

本文主要是介绍LiveData原理解析和仿写一个LiveDataBus,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引入LiveData:

implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"

学习内容:

//这个实际上还是继承了LiveData
public class MutableLiveData<T> extends LiveData<T> {@Overridepublic void postValue(T value) {super.postValue(value);}@Overridepublic void setValue(T value) {super.setValue(value);}
}

开始使用

//初始化
MutableLiveData<String> liveData = new MutableLiveData<>();
//有两种发送值的方式
//第一种
liveData.setValue("123");
//第二种
liveData.postValue("456");

接下来从源码的角度来分析这两个方法的区别。
liveData.postValue

	private final Runnable mPostValueRunnable = new Runnable() {@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}//noinspection unchecked//postValue切换到主线程,最终还是调用了setValue()setValue((T) newValue);}};protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}//可以看到这里我们将赋值的操作切换到主线程,然后再执行。ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}

所以liveData.postValue可以再任意的线程调用,因为最终会切换到主线程。
liveData.setValue

 @MainThreadprotected void setValue(T value) {//断言的方式判断当前是不是主线程assertMainThread("setValue");//每次设置值的时候都会+1mVersion++;mData = value;//分发更新的值dispatchingValue(null);}

所以liveData.setValue只能再主线程中调用。
然后当我们调用了setValue()之后,接着看dispatchingValue这个方法

public abstract class LiveData<T> {static final int START_VERSION = -1;//观察者的 mapprivate SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =new SafeIterableMap<>();private int mVersion = START_VERSION;
......void dispatchingValue(@Nullable ObserverWrapper initiator) {if (mDispatchingValue) {mDispatchInvalidated = true;return;}mDispatchingValue = true;do {mDispatchInvalidated = false;if (initiator != null) {considerNotify(initiator);initiator = null;} else {//因为initiator = null 所以执行这个方法 遍历每个observerfor (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {//执行这个方法considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}//最后调用观察者的回调的方法private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}//这个判断非常重要哦//刚开始的时候这两个值都为-1//所以第一次进来就会return//但setValue()执行后,mVersion就+1了,所以就不会return了//这样保证了观察者的回调方法不会因为生命周期的多次回调而调用多次//这个判断也是我们下文仿写LiveDataBus的重要判断条件if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection unchecked//调用观察者的回调方法,进行更新的操作。observer.mObserver.onChanged((T) mData);}//生命周期改变时会回调
//GenericLifecycleObserver.onStateChanged方法(是感知到生命周期的重要原因)
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}//生命周期改变时会回调这个方法@Overridepublic void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {removeObserver(mObserver);return;}//执行父类里的方法activeStateChanged(shouldBeActive());}@Overrideboolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}@Overridevoid detachObserver() {mOwner.getLifecycle().removeObserver(this);}}private abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;ObserverWrapper(Observer<? super T> observer) {mObserver = observer;}abstract boolean shouldBeActive();boolean isAttachedTo(LifecycleOwner owner) {return false;}void detachObserver() {}void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;boolean wasInactive = LiveData.this.mActiveCount == 0;LiveData.this.mActiveCount += mActive ? 1 : -1;if (wasInactive && mActive) {onActive();}if (LiveData.this.mActiveCount == 0 && !mActive) {onInactive();}if (mActive) {//分发值 需要更新dispatchingValue(this);}}}
}

到这里观察的回调在哪里调用了,我们就搞清了,我们暂时先不要管onStateChanged再生命周期为什么回调,下文会介绍的不要急。
接下来就是设置观察者了。

liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {//在这里处理你自己的逻辑}});

我们就来看这个方法内部是怎么执行的。

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");//判断当前活动是否被销毁,被销毁直接返回,不注册if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);if (existing != null && !existing.isAttachedTo(owner)) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}//所以这里就是等于在activity里写如下的代码//AppCompatActivity.getLifecycle().addObserver(wrapper);//这跟之前我们监听activity生周期的方法一样呢//这就是LiveData为什么能感知生命周期的原因owner.getLifecycle().addObserver(wrapper);}

可以看到这个owner,有的小伙会问,欸?为什么是这个形参的类型是LifecycleOwner这是因为我们的AppCompatActivity继承了FragmentActivity继承了ComponentActivity的实现了LifecycleOwner。

public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {......
}public class FragmentActivity extends ComponentActivity implementsViewModelStoreOwner,ActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {
}public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {
}

现在我们再来看一种代码

MutableLiveData<String> liveData = new MutableLiveData<>();
liveData.setValue("123");
liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}
});

这段代码注意 我们是先发送值,然后注册监听者,大家认为我们可以在onChanged回调时接收到“123”吗?答案是肯定的,但这有点不符合常理了,毕竟我们先发送值,但这时候还没有注册事件监听者,后来才注册的事件监听者,也能收到,这就有点奇怪了,我们来看一下LiveData是怎么实现的。

这就要牵扯到下面这段代码了

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@Override//每次生命周期变化都会调用public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {removeObserver(mObserver);return;}//调用父类里的方法activeStateChanged(shouldBeActive());}.....
}
private abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;.......void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;boolean wasInactive = LiveData.this.mActiveCount == 0;LiveData.this.mActiveCount += mActive ? 1 : -1;if (wasInactive && mActive) {onActive();}if (LiveData.this.mActiveCount == 0 && !mActive) {onInactive();}if (mActive) {//调用更新的值分发dispatchingValue(this);}}}.....
}

这段逻辑,相信从上面看到下面的小伙伴都有印象,所以弄清楚onStateChanged为什么在生命周期改变时会被调用。
owner.getLifecycle().addObserver(wrapper);这句话就是我们观察者被注册到监听者的方法。

public class FragmentActivity extends ComponentActivity implementsViewModelStoreOwner,ActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {.....@Overridepublic Lifecycle getLifecycle() {return super.getLifecycle();}......
}
public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}}

所以当我们getLifecycle().addObserver()得到的对象是LifecycleRegistry.addObserver()

	@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {//获取当前activity处在那个生命周期//DESTROYED:0  INITIALIZED:1State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//下面这两行代码跟LiveData.observe()里的两行代码差不多的ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {pushParentState(statefulObserver.mState);statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));popParentState();// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);}if (!isReentrance) {// we do sync only on the top level.//到这了sync();}mAddingObserverCounter--;}private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "+ "new events from it.");return;}while (!isSynced()) {mNewEventOccurred = false;// no need to check eldest for nullability, because isSynced does it for us.//if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}private void forwardPass(LifecycleOwner lifecycleOwner) {Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =mObserverMap.iteratorWithAdditions();//从观察者map 迭代所有的观察者while (ascendingIterator.hasNext() && !mNewEventOccurred) {Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {pushParentState(observer.mState);//然后就调用这个方法observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));popParentState();}}}private void backwardPass(LifecycleOwner lifecycleOwner) {Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =mObserverMap.descendingIterator();while (descendingIterator.hasNext() && !mNewEventOccurred) {Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {Event event = downEvent(observer.mState);pushParentState(getStateAfter(event));observer.dispatchEvent(lifecycleOwner, event);popParentState();}}}static class ObserverWithState {State mState;GenericLifecycleObserver mLifecycleObserver;ObserverWithState(LifecycleObserver observer, State initialState) {mLifecycleObserver = Lifecycling.getCallback(observer);mState = initialState;}void dispatchEvent(LifecycleOwner owner, Event event) {State newState = getStateAfter(event);mState = min(mState, newState);//然后到这儿就会回调我们在LiveData里的LifecycleBoundObserver的onStateChanged方法mLifecycleObserver.onStateChanged(owner, event);mState = newState;}}

所以sync()方法最终会导致我们的事件回调(记下这个方法名)
然后我们继续

public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {......@Override@SuppressWarnings("RestrictedApi")protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);//看到这里,我们把自己传了进去ReportFragment.injectIfNeededIn(this);}......
}
public class ReportFragment extends Fragment {private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"+ ".LifecycleDispatcher.report_fragment_tag";public static void injectIfNeededIn(Activity activity) {// ProcessLifecycleOwner should always correctly work and some activities may not extend// FragmentActivity from support lib, so we use framework fragments for activities//这里我们看到我们启动了一个ReportFragmentandroid.app.FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.manager.executePendingTransactions();}}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);dispatchCreate(mProcessListener);dispatch(Lifecycle.Event.ON_CREATE);}@Overridepublic void onStart() {super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);}@Overridepublic void onResume() {super.onResume();dispatchResume(mProcessListener);dispatch(Lifecycle.Event.ON_RESUME);}private void dispatch(Lifecycle.Event event) {Activity activity = getActivity();if (activity instanceof LifecycleRegistryOwner) {((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);return;}if (activity instanceof LifecycleOwner) {Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if (lifecycle instanceof LifecycleRegistry) {((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);}}}
.......
}

我们可以看到在ReportFragment的生命周期中都有同一个方法dispatch(),而且最终都会调用getLifecycle().handleLifecycleEvent(event)

 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {State next = getStateAfter(event);moveToState(next);}private void moveToState(State next) {if (mState == next) {return;}mState = next;if (mHandlingEvent || mAddingObserverCounter != 0) {mNewEventOccurred = true;// we will figure out what to do on upper level.return;}mHandlingEvent = true;//看这个sync(),上面我们就见过这个方法,所以就可以说通了sync();mHandlingEvent = false;}

正是通过这个handleLifecycleEvent调用了sync然后再调用了dispatchEvent然后调用了mLifecycleObserver.onStateChanged

但是我们LiveData一般都不是用来监听生命周期的,都是用来组件间通信的所以我就来仿照LiveDataBus写一个自己的组件通信,但是我们有的时候不需要粘性事件(未注册的监听者不因该监听到注册前所发送过的事件),所以我们需要自己实现一个可以控制黏性的事件通知者。

//黏性事件
public class MyLiveDataBus {private static MyLiveDataBus instance = new MyLiveDataBus();private Map<String, MyMutableLiveData<Object>> liveDataMap;public static MyLiveDataBus getInstance(){return instance;}private MyLiveDataBus(){liveDataMap = new HashMap<>();}public synchronized<T> MyMutableLiveData<T> with(String key,Class<T> clazz){if(!liveDataMap.containsKey(key)){liveDataMap.put(key,new MyMutableLiveData<Object>());}return (MyMutableLiveData<T>) liveDataMap.get(key);}private static class MyMutableLiveData<T> extends MutableLiveData<T> {private boolean isSticky = false;public void observe(@NonNull LifecycleOwner owner, boolean isSticky , @NonNull Observer<? super T> observer) {this.isSticky = isSticky ;observe(owner,observer);}@Overridepublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {super.observe(owner, observer);try {if(!isSticky ){hook((Observer<T>) observer);}} catch (Exception e) {e.printStackTrace();}}//让mLastVersion和mVersion相等,这样可以在注册监听的时候就不会回调onStateChanged了private void hook(Observer<T> observer) throws Exception {Class<LiveData> liveDataClass = LiveData.class;Field mObserversField = liveDataClass.getDeclaredField("mObservers");mObserversField.setAccessible(true);Object mObservers = mObserversField.get(this);Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);get.setAccessible(true);Object invokeEntry = get.invoke(mObservers, observer);Object observerWrapper = null;if(invokeEntry!=null && invokeEntry instanceof Map.Entry){observerWrapper = ((Map.Entry)invokeEntry).getValue();}if(observerWrapper == null){throw new NullPointerException("ObserverWrapper不能为空");}Class<?> superclass = observerWrapper.getClass().getSuperclass();Field mLastVersionField = superclass.getDeclaredField("mLastVersion");mLastVersionField.setAccessible(true);Field mVersionField = liveDataClass.getDeclaredField("mVersion");mVersionField.setAccessible(true);Object o = mVersionField.get(this);mLastVersionField.set(observerWrapper,o);}}
}

在Activity中

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);liveData.postValue("123");}}public class TwoActivity extends AppCompatActivity {LiveDataBus2.BusMutableLiveData<String> liveData;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);liveData = LiveDataBus2.getInstance().with("code", String.class);liveData.observe(TwoActivity.this,false, new Observer<String>() {@Overridepublic void onChanged(String s) {Log.e("!!!!!!!!",s);}});}}

这样我们就可以实现MainActivity组件和TwoActivity组件之间的通信了,可以不在使用Intent(大小限制)了。

追记:
LiveData当我们继承自Activity就会报错(之前的都是继承了AppCompatActivity)

public class MainActivity extends Activity {
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyLiveDataBus.MyMutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);//这个observe就会报错 因为继承了ActivityliveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}});liveData.setValue("123");}
}

那我们需要怎么修改呢

public class MainActivity extends Activity {LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);@SuppressLint("RestrictedApi")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ReportFragment.injectIfNeededIn(this);MyLiveDataBus.MyMutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}});liveData.setValue("123");}@NonNull@Overridepublic Lifecycle getLifecycle() {return lifecycleRegistry;}}}

这篇关于LiveData原理解析和仿写一个LiveDataBus的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/718454

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse