Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java/Kotlin:按类ID查找多个哈希集的交集_Java_Kotlin_Set_Guava_Hashset - Fatal编程技术网

Java/Kotlin:按类ID查找多个哈希集的交集

Java/Kotlin:按类ID查找多个哈希集的交集,java,kotlin,set,guava,hashset,Java,Kotlin,Set,Guava,Hashset,我在查找包含数据类的散列集数组的交集时遇到问题(我希望通过标识符进行交集): 我已将.csv文件中的一些数据拉入这种类型的结构: ArrayList<HashSet<Protein>> ArrayList 所以我有六个数组列表[1个用于每个csv],每个列表包含一个包含数千个蛋白质结构的散列集。以下是我到目前为止尝试的基于common Protein.id的交叉点哈希集: fun intersection(data: ArrayList<HashSet<P

我在查找包含数据类的散列集数组的交集时遇到问题(我希望通过标识符进行交集):

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

ArrayList<HashSet<Protein>>
ArrayList
所以我有六个数组列表[1个用于每个csv],每个列表包含一个包含数千个蛋白质结构的散列集。以下是我到目前为止尝试的基于common Protein.id的交叉点哈希集:

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
}
fun交叉点(数据:ArrayList):HashSet{
val intersectionSet=HashSet(数据[0])
用于(i在1..data.size中){
交叉集保留(数据[i])
}
返回交叉集
}
这将返回一个空列表,考虑到它试图与蛋白质对象相交并将每个标准作为一个整体进行匹配,这是有意义的


如何调用数据[I].id作为交点条件?我对Kotlin和数据类相当陌生:)

如果在
Protein
类中添加
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
}
此外,您可能希望将
交叉点
函数中的循环范围更改为
1..(data.size-1)
而不是
1..data.size
,以避免越界。或者,您可以按如下功能编写:

fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {
  return data.reduce { acc, it -> acc.apply { retainAll(it) } }
}
fun交叉点(数据:ArrayList):HashSet{
返回data.reduce{acc,it->acc.apply{retainAll(it)}
}

如果您在
Protein
类中为
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
}
此外,您可能希望将
交叉点
函数中的循环范围更改为
1..(data.size-1)
而不是
1..data.size
,以避免越界。或者,您可以按如下功能编写:

fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {
  return data.reduce { acc, it -> acc.apply { retainAll(it) } }
}
fun交叉点(数据:ArrayList):HashSet{
返回data.reduce{acc,it->acc.apply{retainAll(it)}
}

要简化给定的答案,您可以使用
apply

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) } }
fun multiIntersect(数据:收集)=
HashSet(data.minBy{it.size}!!)。应用{data.forEach{retainAll(it)}

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

请注意,如果您不希望依赖输入成为哈希集,您可以执行以下操作:

fun <T> multiIntersect(data: Collection<Set<T>>) = 
    HashSet(data.minBy { it.size }!!).apply {  data.forEach { retainAll(it) } }
fun multiIntersect(数据:收集)=
HashSet(data.minBy{it.size}!!)。应用{data.forEach{retainAll(it)}

通过从最小的集合开始,您可以潜在地节省大量的运行时间,因为检索集合的大小可以在恒定的时间内完成,就像它保存在对象的字段中一样。

漂亮的解决方案;对于我的交集函数版本和您提供的功能来说,它都是一种魅力。1..data.size调用也很好。后续问题-是否有任何原因需要将hashCode()覆盖指定为Int?当我运行代码而不指定类型时,它的工作原理是相同的。你说得对。没有理由指定类型,因为函数体只是一个表达式,编译器可以推断类型。
等于
时也是如此。我已经更新了答案。漂亮的解决方案;对于我的交集函数版本和您提供的功能来说,它都是一种魅力。1..data.size调用也很好。后续问题-是否有任何原因需要将hashCode()覆盖指定为Int?当我运行代码而不指定类型时,它的工作原理是相同的。你说得对。没有理由指定类型,因为函数体只是一个表达式,编译器可以推断类型。
等于
时也是如此。我已经更新了答案。谢谢!我完全错过了。我刚刚更新了答案。谢谢!我完全错过了。我刚刚更新了答案。