Java &引用;“合并”;数据或;设置“;数据

Java &引用;“合并”;数据或;设置“;数据,java,android-livedata,mediatorlivedata,Java,Android Livedata,Mediatorlivedata,文档()讨论合并数据。。。但功能明确地设置了它 当我想到“合并”时,我会想到像.add()或.put()或.set(X,Y),。。我可以将两个对象捆绑在一个对象中,或者一个OBEJCT列表,或者一个对象数组 但是函数表示.setValue(),文档表示merge 日志给我的印象是前两个setValue()被完全忽略了: 因此,不是: ViewModel: onChnaged: [Folder1, Folder2, Folder3] Fragment: onChanged: Fol

文档()讨论合并数据。。。但功能明确地设置了它

当我想到“合并”时,我会想到像.add()或.put()或.set(X,Y),。。我可以将两个对象捆绑在一个对象中,或者一个OBEJCT列表,或者一个对象数组

但是函数表示.setValue(),文档表示merge

日志给我的印象是前两个setValue()被完全忽略了:

因此,不是:

   ViewModel: onChnaged: [Folder1, Folder2, Folder3]
   Fragment: onChanged: Folder1 ...etc
   ViewModel: onChanged: []
   Fragment: onChanged:
   ViewModel: onChanged: [Quantity1, Quantity2, Quantity3]
   Fragment: onChanged: Quantity1 ...etc
片段上只显示了第一个.setValue(文件夹),我想这只是因为它是3个查询中需要解决的最长的一个


因此,如果我对合并的概念有误解,我需要做一个LiveData/MutableLiveData这个答案是用kotlin写的,希望您能理解或者有人能翻译成java。我有一个扩展,它将3个livedata源合并到一个对象中

分机:

fun <T, A, B, C> LiveData<A>.combineAndCompute3(
    other1: LiveData<B>,
    other2: LiveData<C>,
    onChange: (A, B?, C?) -> T
): LiveData<T> {

    var source0emitted = false
    var source1emitted = false
    var source2emitted = false

    val result = MediatorLiveData<T>()

    val mergeF = {
        val source0Value = this.value
        val source1Value = other1.value
        val source2Value = other2.value

        if (source0emitted && source1emitted && source2emitted) {
            result.value = onChange.invoke(source0Value!!, source1Value, source2Value)
        }
    }

    result.addSource(this) { source0emitted = true; mergeF.invoke() }
    result.addSource(other1) { source1emitted = true; mergeF.invoke() }
    result.addSource(other2) { source2emitted = true; mergeF.invoke() }

    return result
}
fun LiveData.combineandcomputer3(
其他1:LiveData,
其他2:LiveData,
一旦改变:(A,B?,C?->T
):LiveData{
var source0emissed=false
var source1emitted=false
var source2emitted=false
val result=MediatorLiveData()
val mergeF={
val source0Value=this.value
val source1Value=other1.value
val source2Value=other2.value
if(已发出的源0和已提交的源1和已提交的源2){
result.value=onChange.invoke(source0Value!!,source1Value,source2Value)
}
}
result.addSource(this){source0emissed=true;mergeF.invoke()}
result.addSource(other1){source1emitted=true;mergeF.invoke()}
result.addSource(other2){source2emitted=true;mergeF.invoke()}
返回结果
}
在我的viewmodel中,我有如下内容:


    private val _id = MutableLiveData<Int>()
    private val id = _id.distinctUntilChanged()

    private val _name = MutableLiveData<String?>()
    private val name = _name.distinctUntilChanged()

    private val _load = MutableLiveData<Boolean>()
    private val load = _load.distinctUntilChanged()


    private val detailLoad = id.combineAndCompute3(name, load) {
        A, B, C -> DetailLoad(A, B, C)
    }

private val_id=MutableLiveData()
private val id=_id.distinctUntilChanged()
private val_name=MutableLiveData()
private val name=_name.distinctUntilChanged()
private val_load=MutableLiveData()
private val load=_load.distinctUntilChanged()
private val detailLoad=id.CombineAndComputer3(名称、负载){
A、 B,C->DetailLoad(A,B,C)
}

DetailLoad是一个常规数据类,其中a是整数,B是字符串,C是布尔值,我以一种非常标准的方式将值发布到我的mutablelivedatas中。

我将尝试理解您的问题,但只是为了快速澄清。“.combine(data1,data2)”是在您查看它的代码中创建的kotlin扩展。这看起来不错,我很敬畏Kotlin的工作方式。。。我对Java的了解还不够,但是这个:onChange.invoke(source0Value!!,source1Value,source2Value)我会用vargArgs参数创建我自己的观察器来实现它,我不知道你可以在那里传递你想要的任何东西(这是的一个属性),并且非常有趣的是onChanged是如何被“调用”的另外,我也不完全理解onChange是如何被其源代码的每次onChange触发的,我曾经在java中做过类似的事情,但我使用了.wait()来获得其他源代码的答案。谢谢你的回答,这个解决方案的问题是我需要的答案不是“并行”的,而是一个列表,这样我就可以在适配器上提交它们。我的意思是它很有用,你给了我很多想法。。。代码也是一个类吗?还是一个函数?还有,为什么调用时不需要定义它的通配符呢?每次源更改时都会触发onChange。事实上,在我的代码中,只有当所有3个源都发出了某些东西时,它才会发出一个结果。真正控制流的是“result.addSource(){}”,它调用“mergeF.invoke()”,在if语句通过时调用onChange。我认为可以将此代码转换为回答列表。此代码是一个扩展,它是一个函数。你的意思是“id”,这个函数将从任何livedata开始工作,因为它是livedata.CombineAndComputer(),所以我可以从任何livedata开始,它将使用自身(livedata)作为T。我不知道是否正确理解了你的问题。