Java/Kotlin:通过class ID求多个HashSet的交集
Java/Kotlin: Finding the intersection of multiple HashSets by class ID
我在查找包含数据 Class 的散列集数组的交集时遇到问题(我想通过标识符进行交集):
class Protein(val id: String, val score: Double, val molw: Double, val spc: Int)
我已经从 .csv 文件中提取了一些数据到这种类型的结构中:
ArrayList<HashSet<Protein>>
所以我有六个数组列表[每个 csv 一个],每个包含一个包含数千个蛋白质结构的散列集。到目前为止,这是我尝试获得基于 common 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
}
这个 returns 一个空列表,这是有道理的,因为它试图与 Protein 对象相交并匹配每个标准作为一个整体。
如何调用 data[i].id 作为我的交集标准?我对 Kotlin 和数据还很陌生 类 :)
如果您在 Protein
class 中添加 hashCode
和 equals
函数的定义如下,那么 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) } }
}
为了简化给出的答案,您可以使用apply
:
return data.reduce { acc, it -> acc.apply { retainAll(it) } }
请注意,如果您不想依赖于输入成为哈希集,您可以执行以下操作:
fun <T> multiIntersect(data: Collection<Set<T>>) =
HashSet(data.minBy { it.size }!!).apply { data.forEach { retainAll(it) } }
从最小的集合开始,您可以节省大量的运行时间,因为检索集合的大小可以在常量时间内完成,因为它保存在对象的字段中。
我在查找包含数据 Class 的散列集数组的交集时遇到问题(我想通过标识符进行交集):
class Protein(val id: String, val score: Double, val molw: Double, val spc: Int)
我已经从 .csv 文件中提取了一些数据到这种类型的结构中:
ArrayList<HashSet<Protein>>
所以我有六个数组列表[每个 csv 一个],每个包含一个包含数千个蛋白质结构的散列集。到目前为止,这是我尝试获得基于 common 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
}
这个 returns 一个空列表,这是有道理的,因为它试图与 Protein 对象相交并匹配每个标准作为一个整体。
如何调用 data[i].id 作为我的交集标准?我对 Kotlin 和数据还很陌生 类 :)
如果您在 Protein
class 中添加 hashCode
和 equals
函数的定义如下,那么 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) } }
}
为了简化给出的答案,您可以使用apply
:
return data.reduce { acc, it -> acc.apply { retainAll(it) } }
请注意,如果您不想依赖于输入成为哈希集,您可以执行以下操作:
fun <T> multiIntersect(data: Collection<Set<T>>) =
HashSet(data.minBy { it.size }!!).apply { data.forEach { retainAll(it) } }
从最小的集合开始,您可以节省大量的运行时间,因为检索集合的大小可以在常量时间内完成,因为它保存在对象的字段中。