如何查看两个 ArrayList 是否来自同一类型

How to see if two ArrayLists are from the same Type

我正在尝试使用泛型实现视图模型观察器,这样做我不需要 7 个观察器,因为我正在从 7 个不同的片段收集数据。

目标

由于这 7 个片段将数据存储在不同的 ArrayLists 类型中,我制作了一个通用的 ViewModel class 以将该数据传递给我的主要 Activity(片段持有者)

SharedViewModel

class SharedViewModel<T>: ViewModel() {

    var data:MutableLiveData<ArrayList<T>> = MutableLiveData()

    fun setData(anyData:ArrayList<T>){
        data.value = anyData
    }

    val getAnyData:LiveData<ArrayList<T>>
    get() = data

}

这样做,我只是在每个片段中设置任何数组数据类型

  (activity as MainActivity).getViewModelInstance().setData(xArray)

并且在我的 MainActivity 中,我想检查 xArray 数据类型是否与在 MainActivity 中全局声明的类型相同,如果它们相等,则应该评估当前数组数据值到新的空数组

主要Activity

private var xArray = arrayListOf<Xclass>()

    onCreate()
    ...

     viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
            viewModel.getAnyData.observe(this, Observer { it:ArrayList<out Any?>
                if(it == xArray){
                    xArray.addAll(it)
                }
            })

目的

如果我这样做,我会阻止在我的 MainActivity 中为每个片段做 7 个观察者,而只用不同的数组类型更新一个观察者,比较它们并重新分配它们对我来说会更少代码并且更容易对于架构。

问题

有两个问题

.setData(xArray) 其突出显示的红色字样 Required: Nothing, Found:ArrayList<Xclass>。这很奇怪,因为 SharedViewModel 的 setData 需要传递 Any ArrayList。

谢谢

经过一番思考,我想出了一个简单但不会失败的方法,即利用 Class 类型结合泛型来实现完整功能。我相信这将以您希望的方式处理您的可重用性和删除冗余侦听器的问题。

class SharedViewModel <T> (val listType: Class<T>) : ViewModel() {

    var data: MutableLiveData<ArrayList<T>> = MutableLiveData()

    fun setData(anyData: ArrayList<T>) {

        data.value = anyData
    }

    inline fun <reified K> isOfInternalType(checkType: Class<K>): Boolean = checkType.typeName == listType.typeName
}

通过viewModel设置数组数据

class Xclass
var xArray = arrayListOf<Xclass>()

val viewModel = (activity as MainActivity).getViewModelInstance()
if (viewModel.isOfInternalType(Xclass::class.java) {
    viewModel.setData(Xclass)
}

主要Activity

class Xclass
private var xArray = arrayListOf<Xclass>()

onCreate()
...

viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
viewModel.getAnyData.observe(this, Observer { data: ArrayList<out Any?> ->
    if (viewModel.isOfInternalType(Xclass::class.java) {
        xArray.addAll(it)
    }
})

其他示例使用

// Examples of use cases outside of initial question

class ViewOne: SharedView<ClassOne>(ClassOne::class.java)
val testClass = ViewOne()

ViewOne().isOfInternalType(ClassTwo::class.java) // returns false
ViewOne().isOfInternalType(testClass::class.java) // Error: Cannot use captured type as reified parameter

ViewOne().isOfInternalType(ClassOne::class.java) // returns true
ViewOne().isOfInternalType(ClassOne().javaClass) // returns true
testClass.isOfInternalType(ClassOne::class.java) // returns true

我所做的是创建实例化时预期的 View 的 listType 实例。这需要完成,因为 类 不像内联函数那样支持类型具体化。 此实现假设每个视图都有一个静态列表类型...这可以修改为类似于以下内容:

class SharedViewModel(listType: Class<*>) : ViewModel() {
    var listType: Class<*> = listType
    private set(value) {
        field = value
    }

    fun setData(anyData: ArrayList<*>) {
        data.value = anyData
    }

    fun updateListType(newType: Class<*>) {
        listType = newType
    }

    inline fun <reified K> isOfInternalType(checkType: Class<K>): Boolean =
        checkType.typeName == listType.typeName
}

可变类型 SharedViewModel 示例

class ViewOne: SharedView(ClassOne::class.java)

val testClass = ViewOne()

testClass.isOfInternalType(ClassOne::class.java) // returns true

testClass.updateListType(ClassTwo::class.java)

testClass.isOfInternalType(ClassOne::class.java)  // returns false now
testClass.isOfInternalType(ClassTwo::class.java)  // returns true now

通过变量类型的实现,您可能希望将 isOfInternalTypesetData 链接起来,以确保您的类型安全

这应该有足够的功能让你能够完成这个项目的架构目标,如果我有任何误解,请告诉我,并且可以提供进一步的帮助。