網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
背景
- 現(xiàn)有一個(gè)StateFlow及其監(jiān)聽
private val stateFlow = MutableStateFlow(kotlin.Pair<String, ArrayList<String>>("abc", ArrayList()))
GlobalScope.launch {
stateFlow.collect {
// do something
}
}
- 更新ArrayList并嘗試emit
GlobalScope.launch {
stateFlow.value.second.add("test")
stateFlow.emit(stateFlow.value)
}
實(shí)際上,collect并不會(huì)被調(diào)用
原因
MutableStateFlow真正的實(shí)現(xiàn)者是StateFlowImpl, emit方法代碼如下:
override suspend fun emit(value: T) {
this.value = value
}
查看value的set方法:
public override var value: T
get() = NULL.unbox(_state.value)
set(value) { updateState(null, value ?: NULL) }
private fun updateState(expectedState: Any?, newState: Any): Boolean {
var curSequence = 0
var curSlots: Array<StateFlowSlot?>? = this.slots // benign race, we will not use it
synchronized(this) {
val oldState = _state.value
if (expectedState != null && oldState != expectedState) return false // CAS support
if (oldState == newState) return true // Don't do anything if value is not changing, but CAS -> true
_state.value = newState
curSequence = sequence
... 省略部分代碼
}
}
其中"if (oldState == newState) return true"因emit前后是同一個(gè)對(duì)象,導(dǎo)致條件為true,那么,如果emit前后不是同一個(gè)對(duì)象,即可解決這個(gè)問(wèn)題?
另一個(gè)問(wèn)題
emit時(shí)嘗試以下代碼:
GlobalScope.launch {
stateFlow.value.apply {
stateFlow.emit(kotlin.Pair(first, second))
}
}
實(shí)際上,上述代碼仍舊不能解決問(wèn)題,因?yàn)閗otlin.Pair默認(rèn)重寫了equals方法,查看kotlin.Pair decompiled的Java文件
public final class Pair {
public int hashCode() {
Object var10000 = this.first;
int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;
Object var10001 = this.second;
return var1 + (var10001 != null ? var10001.hashCode() : 0);
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof Te.Pair) {
Te.Pair var2 = (Te.Pair) var1;
if (Intrinsics.areEqual(this.first, var2.first) && Intrinsics.areEqual(this.second, var2.second)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
其中Intrinsics.areEqual代碼如下:
public static boolean areEqual(Object first, Object second) {
return first == null ? second == null : first.equals(second);
}
故即使pair對(duì)象本身不一樣,但由于kotlin默認(rèn)重寫了equals方法,而pair.first與pair.second是一樣的,從而條件"if (oldState == newState) return true"成立
解決辦法
由于StateFlow源碼無(wú)法修改且是特定場(chǎng)景需求,故無(wú)法將判斷條件改為kotlin的"===";故使用android.util.Pair或者自定義java Pair class即可
結(jié)論
kotlin class默認(rèn)實(shí)現(xiàn)了equals方法,判斷的是內(nèi)容相等,而Java的class判斷的是地址相等,故判斷對(duì)象相等時(shí)需注意此細(xì)節(jié),根據(jù)需求來(lái)判斷地址相等(===)還是內(nèi)容相等(==)
原文鏈接:https://juejin.cn/post/7086338636802687006
相關(guān)推薦
- 2022-04-08 詳解RIFF和WAVE音頻文件格式_相關(guān)技巧
- 2022-08-06 Golang詳細(xì)講解常用Http庫(kù)及Gin框架的應(yīng)用_Golang
- 2022-11-20 Postgresql刪除數(shù)據(jù)庫(kù)表中重復(fù)數(shù)據(jù)的幾種方法詳解_PostgreSQL
- 2023-05-31 Pandas提取含有指定字符串的行(完全匹配,部分匹配)_python
- 2022-11-12 C語(yǔ)言字符串與字符數(shù)組面試題中最易錯(cuò)考點(diǎn)詳解_C 語(yǔ)言
- 2022-08-02 shell自動(dòng)拉取鏡像并運(yùn)行容器的shell腳本_linux shell
- 2022-02-12 C語(yǔ)言-剖析數(shù)據(jù)是如何在內(nèi)存中存儲(chǔ)的(整型與浮點(diǎn)型)
- 2022-04-04 react解包并配置Less解包c(diǎn)onfig文件目錄
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支