微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Kotlin 泛型 - 可以像 ordinals 方法那样为 Enum 定义的类传递任何类型的元素的整数位置?

如何解决Kotlin 泛型 - 可以像 ordinals 方法那样为 Enum 定义的类传递任何类型的元素的整数位置?

有一种内置的方式可以满足我的要求吗?

我知道 Set 是无序的

我需要做一个基于向量的集合。

我需要知道泛型类型的任何值的位置,以便将它们放在数组的相应索引中,这样我就可以避免元素的重复。

我不是在订购或定义 Set 的顺序。 我没有任何操作不当或破坏任何 Set Cotraint

请注意,我知道这种实现对于像整数这样看起来无限的任何类型都无效。

我需要出于教育目的而这样做。

我已经实现了基于 List Ordered 和 Hash Table 的。

现在我有这门课,它完美无缺:

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)

}

我现在需要以相同的方式创建另一个类,但要使用 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 代表字符)。

  • 值范围/最大值代表任何“显然 无限”类型,如整数。

谢谢!

附言= 请考虑我不是英语母语,请耐心等待!

解决方法

正如有人向我指出的那样,一些代表实数的抽象类型不能那么容易地完成。

枚举类的实现完美无缺,但我的大学教授拒绝了它,因为我需要对相同数据结构的每个实现使用相同的语法。

我有其他实现

- HashTableSet<T>
- OrderedListSet<T>

他们只要求一个抽象类型,可以是任何类型,他们会毫无问题地工作。

我需要对 ArraySet<E : Enum<E>>

所以如果这不能用泛型轻松完成,直接...

我正在考虑混合它们。

就像我拥有的​​任何 T 型一样 它创建了一个名为“Domain”的对象,因此无论它插入什么元素,在将它们放入集合的数组之前,它都会以特定的顺序将它们放入其中,以便模拟它正在执行的枚举。

我猜枚举不能在运行时动态定义。

那么可能我必须将 Domain<T> 定义为私有类/对象(不确定):

  • 使用操作符.insert()收集ArraySet(above MySet)插入的元素
  • 它根据已经在里面的元素对元素进行排序
  • 一旦被命令删除所有的重复
  • 在每次使用插入时根据域的增长方式重新排列整个布尔数组。 (或找出部分重新排列布尔数组的不同算法)

你怎么看?

给我更多建议,谢谢。

,

Enum 以声明顺序隐式排序,并且每个枚举的实例数量是有限的,因此它们可以全局排序并且它们的序数可以表示为 Int .

Ints(以及 Bytes 和 Chars)是自然排序的并且有范围(Int.MIN_VALUE..Int.MAX_VALUE 等),所以它们中的每一个都可以有一个序数也表示为Int

所有实现 Comparable 接口的类型都可以成对比较,并且可以对它们的任何子集进行排序,但这并不意味着它们每个都有一些全局 Int ordinal 在所有可能的实例中,因为 Int 的集合是有限的(2^32 项),并且泛型类型 T 的所有唯一实例的集合可以是可数无限的(例如 {{1} }) 甚至不可数(如 BigInteger)(见 wiki about cardinality)。

所有其他类型甚至不能成对比较(没有尊重的Double)。

因此,您需要手动限制将要添加到您的集合中的每个 Comparator<T> 的实例,并手动对它们进行排序或提供尊重的 T 以构建您所需要的 Comparator<T>需要用于后续的序数求值:

Map<T,Int>

用法:

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>

你也可以定义辅助函数,概括以前的方法:

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()
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。