如何将数据类型映射到该数据类型的集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将数据类型映射到该数据类型的集合相关的知识,希望对你有一定的参考价值。

代码:

abstract class DataContainer(public val path: String)
val preloaded: MutableMap<Class<out DataContainer>, HashSet<out DataContainer>> = hashMapOf()

我想知道如何让Kotlin意识到第一个out DataContainer与第二个out DataContainer是同一类型。 所以代码就像:

fun <D: DataContainer> get(clazz: Class<D>): HashSet<D> = preloaded[clazz] as HashSet<D>

不需要as HashSet<D>(并且不容易出现错误)。我是Kotlin的新手,如果我错过了某些内容,请链接文档。此外,如果重要,此代码将在object内。

答案

我认为你想要的东西在语言水平上是不可行的。

get方法中的演员阵容并不是那么糟糕,只要你能安全地完成它。我能够安全地看到这一点的唯一方法是控制put方法。

如果强制D : DataContainer类型的每个键都与Set<D>类型的键配对,则可以在获取时安全地进行转换。例如,你可以这样:

object DataContainerRegistry {

    private val preloaded: MutableMap<Class<out DataContainer>, HashSet<DataContainer>> = hashMapOf()

    fun put(dataContainer: DataContainer) {
        val set = preloaded.getOrDefault(dataContainer::class.java, HashSet())
        set.add(dataContainer)
        preloaded[dataContainer::class.java] = set
    }

    fun <D : DataContainer> get(clazz: Class<D>) = preloaded.getOrDefault(clazz, HashSet()) as Set<D>

}

这种方法的局限性是:

  1. 只有一个类(在我的例子中为DataContainerRegistry singleton)可以直接访问preloaded地图
  2. get方法只返回Set,而不是可变接口。

这样你就知道没有人会把preloaded和其中包含的每个Set弄得乱七八糟,然后你可以轻松地投射。

另一答案

部分内容是Java语言的基础。

举个例子,假设你有一组Animal对象。你可以把CatDog放在那里,但是当谈到特别拔出一个Cat时,你必须通过使用演员来断言它确实是一个Cat

但是,如果您愿意将您的集合的特定实例限制为仅处理CatDog,那么这样可以正常工作。

那么,让我们假设我们有:

abstract class DataContainer(public val path: String)

abstract class CatDataContainer(path: String): DataContainer(path)

abstract class DogDataContainer(path: String): DataContainer(path)

那只是你的DataContainer和两个子类。

如果我们在拥有您的地图的类上放置一个类型参数,我们可以这样做:

class TypedContainerHolder1<D: DataContainer> {

    val preloaded: MutableMap<Class<out D>, HashSet<out D>> = hashMapOf()

    fun get(clazz: Class<D>): HashSet<out D>? = preloaded[clazz]
}

val typedContainerHolder1 = TypedContainerHolder1<CatDataContainer>()

此外,我们可以通过将映射限制为相同的键/值对类型来改进。这也使用了Kotlin的代表团。

class TypedContainerHolder2<D: DataContainer> {

    inner class PreloadedMap<MapType : D> : Map<Class<out MapType>, HashSet<out MapType>> by hashMapOf()

    private val preloaded = PreloadedMap<D>()

    fun get(clazz: Class<D>): HashSet<out D>? = preloaded[clazz]
}

val typedContainerHolder2 = TypedContainerHolder2<DogDataContainer>()

没有演员表,一旦你设置它就会更安全。问题是您的方案是否允许此约束。

以上是关于如何将数据类型映射到该数据类型的集合的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate学习笔记 --- 映射基本数据类型的List集合

如何将多个值类型集合映射到 Hibernate 中的一个表?

AutoMapper 5. 集合类型之间的转换

JPA集合映射

如何在OpenCV中使用双重类型的地图重新映射

如何将设置数据类型放入Firestore?