【问题标题】:Java/Kotlin: Finding the intersection of multiple HashSets by class IDJava/Kotlin:通过类 ID 查找多个 HashSet 的交集
【发布时间】:2018-04-18 04:45:07
【问题描述】:

我无法找到包含数据类的哈希集数组的交集(我想通过标识符相交):

class Protein(val id: String, val score: Double, val molw: Double, val spc: Int)

我已将 .csv 文件中的一些数据提取到这种类型的结构中:

ArrayList<HashSet<Protein>>

所以我有六个数组列表 [每个 csv 1 个],每个列表都包含一个包含数千个蛋白质结构的散列集。到目前为止,这是我尝试获取基于常见 Protein.id 的交集 HashSet 的方法:

fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {

val intersectionSet = HashSet<Protein>(data[0])

for (i in 1..data.size) {
    intersectionSet.retainAll(data[i])
}
return intersectionSet
}

这会返回一个空列表,考虑到它试图与 Protein 对象相交并作为一个整体匹配每个条件,这是有道理的。

如何调用 data[i].id 作为我的交集条件?我对 Kotlin 和数据类还很陌生 :)

【问题讨论】:

    标签: java kotlin set guava hashset


    【解决方案1】:

    为了简化给出的答案,您可以使用apply

    return data.reduce { acc, it -> acc.apply { retainAll(it) } }
    

    【讨论】:

    • 谢谢!我完全错过了。我刚刚更新了答案。
    【解决方案2】:

    如果您在Protein 类中添加hashCodeequals 函数的定义,如下所示,那么HashSet 将能够使用id 字段适当地检查交集。

    class Protein(val id: String, val score: Double, val molw: Double, val spc: Int) {
      override fun hashCode() = id.hashCode()
      override fun equals(other: Any?) = other?.let { id == (it as Protein).id } ?: false
    }
    

    此外,您可能希望将 intersection 函数内的循环范围更改为 1..(data.size-1) 而不是 1..data.size 以避免超出范围。或者,您可以按如下方式编写它:

    fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {
      return data.reduce { acc, it -> acc.apply { retainAll(it) } }
    }
    

    【讨论】:

    • 漂亮的解决方案;对于我的交集函数版本和您提供的内容来说,它就像一个魅力。 1..data.size 调用也很好。跟进 Q - 是否有任何理由需要将 hashCode() 覆盖指定为 Int?当我在不指定类型的情况下运行代码时,它的工作原理是一样的。
    • 你是对的。没有理由指定类型,因为函数体只是一个表达式,编译器可以推断类型。 equals 也是如此。我已经更新了答案。
    【解决方案3】:

    请注意,如果您不想依赖输入成为 Hashset,您可以执行以下操作:

    fun <T> multiIntersect(data: Collection<Set<T>>) = 
        HashSet(data.minBy { it.size }!!).apply {  data.forEach { retainAll(it) } }
    

    从最小的集合开始,您可能会节省大量运行时间,因为检索集合的大小可以在恒定时间内完成,因为它保存在对象的字段中。

    【讨论】:

      猜你喜欢
      • 2022-06-11
      • 2017-05-31
      • 2019-01-16
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-28
      • 2023-03-21
      相关资源
      最近更新 更多