Kotlin Generics - 可以像序数方法为枚举定义的 类 一样获取传递的任何类型的元素的整数位置?
Kotlin Generics - It is possible get integer position of an element of whatever type passed like ordinals method does for Enum defined classes?
有内置的方法可以满足我的要求吗?
我知道 Set 是无序的
我需要做一个基于向量的集合。
我需要知道泛型类型的任何值的位置,以便将它们放在数组的相应索引中,这样我就可以避免元素重复。
我不是在订购或定义 Set 的顺序。
我没有任何行为不当或破坏任何 Set Costraint
的运算符
请注意,我知道此实现对于任何看起来无限的类型(如整数)都不是有效的。
出于教育目的,我需要这样做。
我已经实现了基于 List Ordered 和 Hash Table 的。
现在我有这个 class,可以完美地工作:
package ads
class MySet<E : Enum<E>> {
//More details for clarify
private val maxSet = 127
private var myset = arrayOfNulls<Boolean>(maxSet)
private fun getOrdinal(eelement : E) : Int{
return eelement.ordinal
}
/*
more set operators that needs of getOrdinal
*/
fun insert(xelement: E){
myset[getOrdinal(xelement)] = true
}
}
import ads.MySet as RawSet
enum class MyColors{
Red,
Green,
Blue,
Yellow,
Black,
Mint;
}
fun main() {
val myfavc = RawSet<MyColors>()
val yourfavc = RawSet<MyColors>()
//Following operations...
myfavc.insert(MyColors.Red)
yourfavc.insert(MyColors.Blue)
}
我现在需要以相同的方式制作另一个 class,但使用 kotlin 中已经定义的任何抽象类型。
package ads
class MySet<T> {
//More details for clarify
private val maxSet = 127
private var myset = arrayOfNulls<Boolean>(maxSet)
private fun getOrdinal(telement : T) : Int{
/*
For any abstract type return the order of any element
checks if the integer is not greater than maxSet otherwhise it
throws an Exception or manages this istance in other way
*/
}
/*
more set operators that needs of getOrdinal
*/
fun insert(xelement: T){
myset[getOrdinal(xelement)] = true
}
}
import ads.MySet as RawSeT
//Istance using Int
fun main() {
val myfav = RawSet<Int>()
val yourfav = RawSet<Int>()
//Following operations...
myfav.insert(11)
yourfav.insert(123)
}
我想没有以通用方式执行此操作的内置方法。
但我仍在学习 kotlin,所以也许我遗漏了一些有用的东西。
我不是要写论文。
我不需要我应该自己找出的完整替代解决方案,但是
我愿意阅读任何可以帮助我阐明抽象类型在 Kotlin(或编程语言)中如何工作的技巧或资源信息,例如:
如何排序。
如果任何类型的任何值都可以根据它们的位置进行比较
(比如 c > a 表示字符)。
values/Max 值范围表示任何“显然
infinite" 类型,如整数。
谢谢!
P.S。 = 请考虑我不是英语母语,请耐心等待!
正如有人向我指出的那样,一些代表实数的抽象类型不能那么容易地完成。
枚举 class 的实现完美无缺,但我的大学教授拒绝了它,因为我需要对相同数据结构的每个实现使用相同的语法。
我有其他实现
- HashTableSet<T>
- OrderedListSet<T>
他们只要求一个可以是任何类型的抽象类型,他们将毫无问题地工作。
我需要对
ArraySet<E : Enum<E>>
所以如果这不能用泛型轻松完成,直接...
我正在考虑混合它们。
喜欢我拥有的任何T型
它创建一个名为“Domain”的对象,因此无论它插入什么元素,在将它们放入集合数组之前,它都会以特定顺序将它们放入其中,以便模拟它正在执行的枚举。
我猜枚举不能在运行时动态定义。
那么我可能必须将 Domain<T>
定义为私有 class/object(不确定):
- 收集ArraySet(MySet之上)实例的元素,插入操作符.insert()
- 它将元素与已经在里面的元素进行比较排序
- 一旦命令删除所有双胞胎
- 根据域的增长情况,每次使用插入时重新排列整个布尔数组。 (或者找到一个不同的算法,部分重新排列布尔数组)
你怎么看?
多多指教,谢谢
Enum
s 按声明顺序隐式排序并且每个枚举的实例数量是有限的,因此它们可以全局排序并且它们的 ordinal 可以表示为Int
.
Int
s(以及 Byte
s 和 Char
s)是自然有序的并且有范围(Int.MIN_VALUE..Int.MAX_VALUE
等),所以它们中的每一个也可以有一个 序数 表示为 Int
。
所有实现 Comparable
接口的类型都可以成对比较,并且可以对它们实例的任何子集进行排序,但这并不意味着它们中的每一个都有一些全局 Int
ordinal 在所有可能的实例中,因为 Int
s 的集合是有限的(2^32 项),而通用类型 T
的所有唯一实例的集合可以是无限的(像 BigInteger
) 甚至是不可数的(像 Double
)(参见 wiki about cardinality)。
所有其他类型甚至无法成对比较(没有尊重 Comparator<T>
)。
因此您需要手动限制每个 T
将要添加到您的集合中的实例,并手动订购它们或提供尊重的 Comparator<T>
来构建一个 Map<T, Int>
您将需要用于后续的 ordinal 评估:
class SetOfSomehowOrderedInstancesOfType<T>(private val order: Map<T, Int>) {
private val maxSet = order.size
private var myset = BooleanArray(order.size)
private fun getOrdinal(eelement: T): Int {
return order[eelement] ?: throw RuntimeException("Order unknown")
}
fun insert(xelement: T) {
myset[getOrdinal(xelement)] = true
}
}
用法:
fun main() {
val myFavouriteRealNumbersInMyFavouriteOrder =
listOf(99.2123, -2355.12, 1.1, 3.14, 100.0, 123214214215.123331322145)
val myfavc = SetOfSomehowOrderedInstancesOfType<Double>(myFavouriteRealNumbersInMyFavouriteOrder.mapToIndex())
myfavc.insert(99.2123) //will be inserted with ordinal = 0
val myFavouriteRealNumbersInNaturalOrder = myFavouriteRealNumbersInMyFavouriteOrder.sorted()
val yourfavc = SetOfSomehowOrderedInstancesOfType<Double>(myFavouriteRealNumbersInNaturalOrder.mapToIndex())
yourfavc.insert(99.2123) //will be inserted with ordinal = 3
}
或者您可以定义 Orderable
和 Ordinator<T>
接口(类似于 Comparable<T>
和 Comparator<T>
)并确定 ordinal 使用他们:
fun interface Ordinator<T> {
fun getOrderOf(x : T) : Int
}
interface Orderable {
val order : Int
}
class MySet<T>(private val ordinator: Ordinator<T>? = null) {
private val maxSet = 127
private var myset = BooleanArray(maxSet)
private fun getOrdinal(eelement: T) = when {
eelement is Orderable -> eelement.order
ordinator != null -> ordinator.getOrderOf(eelement)
else -> throw RuntimeException()
}
fun insert(xelement: T) {
myset[getOrdinal(xelement)] = true
}
}
你也可以定义辅助函数,概括以前的方法:
fun <T> ordinatorOf(order: List<T>) = object : Ordinator<T> {
private val order = order.mapToIndex()
override fun getOrderOf(x: T) = this.order[x] ?: throw RuntimeException()
}
用法:
val stringsOrderedByTheirLength = MySet<String> { it.length }
stringsOrderedByTheirLength.insert("aaa") //will be inserted with ordinal = 3
val myFavouriteRealNumbersInMyFavouriteOrder =
listOf(99.2123, -2355.12, 1.1, 3.14, 100.0, 123214214215.123331322145)
val myfavc = MySet(ordinatorOf(myFavouriteRealNumbersInMyFavouriteOrder))
myfavc.insert(99.2123) //will be inserted with ordinal = 0
有内置的方法可以满足我的要求吗?
我知道 Set 是无序的
我需要做一个基于向量的集合。
我需要知道泛型类型的任何值的位置,以便将它们放在数组的相应索引中,这样我就可以避免元素重复。
我不是在订购或定义 Set 的顺序。 我没有任何行为不当或破坏任何 Set Costraint
的运算符请注意,我知道此实现对于任何看起来无限的类型(如整数)都不是有效的。
出于教育目的,我需要这样做。
我已经实现了基于 List Ordered 和 Hash Table 的。
现在我有这个 class,可以完美地工作:
package ads
class MySet<E : Enum<E>> {
//More details for clarify
private val maxSet = 127
private var myset = arrayOfNulls<Boolean>(maxSet)
private fun getOrdinal(eelement : E) : Int{
return eelement.ordinal
}
/*
more set operators that needs of getOrdinal
*/
fun insert(xelement: E){
myset[getOrdinal(xelement)] = true
}
}
import ads.MySet as RawSet
enum class MyColors{
Red,
Green,
Blue,
Yellow,
Black,
Mint;
}
fun main() {
val myfavc = RawSet<MyColors>()
val yourfavc = RawSet<MyColors>()
//Following operations...
myfavc.insert(MyColors.Red)
yourfavc.insert(MyColors.Blue)
}
我现在需要以相同的方式制作另一个 class,但使用 kotlin 中已经定义的任何抽象类型。
package ads
class MySet<T> {
//More details for clarify
private val maxSet = 127
private var myset = arrayOfNulls<Boolean>(maxSet)
private fun getOrdinal(telement : T) : Int{
/*
For any abstract type return the order of any element
checks if the integer is not greater than maxSet otherwhise it
throws an Exception or manages this istance in other way
*/
}
/*
more set operators that needs of getOrdinal
*/
fun insert(xelement: T){
myset[getOrdinal(xelement)] = true
}
}
import ads.MySet as RawSeT
//Istance using Int
fun main() {
val myfav = RawSet<Int>()
val yourfav = RawSet<Int>()
//Following operations...
myfav.insert(11)
yourfav.insert(123)
}
我想没有以通用方式执行此操作的内置方法。 但我仍在学习 kotlin,所以也许我遗漏了一些有用的东西。
我不是要写论文。
我不需要我应该自己找出的完整替代解决方案,但是 我愿意阅读任何可以帮助我阐明抽象类型在 Kotlin(或编程语言)中如何工作的技巧或资源信息,例如:
如何排序。
如果任何类型的任何值都可以根据它们的位置进行比较 (比如 c > a 表示字符)。
values/Max 值范围表示任何“显然 infinite" 类型,如整数。
谢谢!
P.S。 = 请考虑我不是英语母语,请耐心等待!
正如有人向我指出的那样,一些代表实数的抽象类型不能那么容易地完成。
枚举 class 的实现完美无缺,但我的大学教授拒绝了它,因为我需要对相同数据结构的每个实现使用相同的语法。
我有其他实现
- HashTableSet<T>
- OrderedListSet<T>
他们只要求一个可以是任何类型的抽象类型,他们将毫无问题地工作。
我需要对
ArraySet<E : Enum<E>>
所以如果这不能用泛型轻松完成,直接...
我正在考虑混合它们。
喜欢我拥有的任何T型 它创建一个名为“Domain”的对象,因此无论它插入什么元素,在将它们放入集合数组之前,它都会以特定顺序将它们放入其中,以便模拟它正在执行的枚举。
我猜枚举不能在运行时动态定义。
那么我可能必须将 Domain<T>
定义为私有 class/object(不确定):
- 收集ArraySet(MySet之上)实例的元素,插入操作符.insert()
- 它将元素与已经在里面的元素进行比较排序
- 一旦命令删除所有双胞胎
- 根据域的增长情况,每次使用插入时重新排列整个布尔数组。 (或者找到一个不同的算法,部分重新排列布尔数组)
你怎么看?
多多指教,谢谢
Enum
s 按声明顺序隐式排序并且每个枚举的实例数量是有限的,因此它们可以全局排序并且它们的 ordinal 可以表示为Int
.
Int
s(以及 Byte
s 和 Char
s)是自然有序的并且有范围(Int.MIN_VALUE..Int.MAX_VALUE
等),所以它们中的每一个也可以有一个 序数 表示为 Int
。
所有实现 Comparable
接口的类型都可以成对比较,并且可以对它们实例的任何子集进行排序,但这并不意味着它们中的每一个都有一些全局 Int
ordinal 在所有可能的实例中,因为 Int
s 的集合是有限的(2^32 项),而通用类型 T
的所有唯一实例的集合可以是无限的(像 BigInteger
) 甚至是不可数的(像 Double
)(参见 wiki about cardinality)。
所有其他类型甚至无法成对比较(没有尊重 Comparator<T>
)。
因此您需要手动限制每个 T
将要添加到您的集合中的实例,并手动订购它们或提供尊重的 Comparator<T>
来构建一个 Map<T, Int>
您将需要用于后续的 ordinal 评估:
class SetOfSomehowOrderedInstancesOfType<T>(private val order: Map<T, Int>) {
private val maxSet = order.size
private var myset = BooleanArray(order.size)
private fun getOrdinal(eelement: T): Int {
return order[eelement] ?: throw RuntimeException("Order unknown")
}
fun insert(xelement: T) {
myset[getOrdinal(xelement)] = true
}
}
用法:
fun main() {
val myFavouriteRealNumbersInMyFavouriteOrder =
listOf(99.2123, -2355.12, 1.1, 3.14, 100.0, 123214214215.123331322145)
val myfavc = SetOfSomehowOrderedInstancesOfType<Double>(myFavouriteRealNumbersInMyFavouriteOrder.mapToIndex())
myfavc.insert(99.2123) //will be inserted with ordinal = 0
val myFavouriteRealNumbersInNaturalOrder = myFavouriteRealNumbersInMyFavouriteOrder.sorted()
val yourfavc = SetOfSomehowOrderedInstancesOfType<Double>(myFavouriteRealNumbersInNaturalOrder.mapToIndex())
yourfavc.insert(99.2123) //will be inserted with ordinal = 3
}
或者您可以定义 Orderable
和 Ordinator<T>
接口(类似于 Comparable<T>
和 Comparator<T>
)并确定 ordinal 使用他们:
fun interface Ordinator<T> {
fun getOrderOf(x : T) : Int
}
interface Orderable {
val order : Int
}
class MySet<T>(private val ordinator: Ordinator<T>? = null) {
private val maxSet = 127
private var myset = BooleanArray(maxSet)
private fun getOrdinal(eelement: T) = when {
eelement is Orderable -> eelement.order
ordinator != null -> ordinator.getOrderOf(eelement)
else -> throw RuntimeException()
}
fun insert(xelement: T) {
myset[getOrdinal(xelement)] = true
}
}
你也可以定义辅助函数,概括以前的方法:
fun <T> ordinatorOf(order: List<T>) = object : Ordinator<T> {
private val order = order.mapToIndex()
override fun getOrderOf(x: T) = this.order[x] ?: throw RuntimeException()
}
用法:
val stringsOrderedByTheirLength = MySet<String> { it.length }
stringsOrderedByTheirLength.insert("aaa") //will be inserted with ordinal = 3
val myFavouriteRealNumbersInMyFavouriteOrder =
listOf(99.2123, -2355.12, 1.1, 3.14, 100.0, 123214214215.123331322145)
val myfavc = MySet(ordinatorOf(myFavouriteRealNumbersInMyFavouriteOrder))
myfavc.insert(99.2123) //will be inserted with ordinal = 0