如何将数据类型映射到该数据类型的集合
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>
}
这种方法的局限性是:
- 只有一个类(在我的例子中为
DataContainerRegistry
singleton)可以直接访问preloaded
地图 get
方法只返回Set
,而不是可变接口。
这样你就知道没有人会把preloaded
和其中包含的每个Set
弄得乱七八糟,然后你可以轻松地投射。
部分内容是Java语言的基础。
举个例子,假设你有一组Animal
对象。你可以把Cat
和Dog
放在那里,但是当谈到特别拔出一个Cat
时,你必须通过使用演员来断言它确实是一个Cat
。
但是,如果您愿意将您的集合的特定实例限制为仅处理Cat
或Dog
,那么这样可以正常工作。
那么,让我们假设我们有:
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集合