由于迭代器没有删除方法,我该如何将其转换为Scala?
iter的定义如下:
Iterator<Integer> iter = cache.keySet().iterator();
这里的cache是一个哈希表
while (iter.hasNext()) {
int num = iter.next();
if (!part.contains(num)){
iter.remove();
}
}
如果您的实际目标是从缓存中过滤一些键,您可以直接进行操作,无需使用循环和迭代器:
val cache = Map("a" -> 3, "b" -> 5, "c" -> 7)
val part = Set("x", "y", "b")
val filteredCache = cache.filter{ case (k, _) => part.contains(k) }
// prints `Map(b -> 5)`, because "a" and "c" not in `part`
println(filteredCache)
编辑
正如@SymY4所指出的,filter
和filterKeys
的行为有很大不同:filter
会返回一个新的Map(不可变版本),或将元素就地过滤(可变版本)。然而,filterKeys
只构建原始集合的过滤视图。因此,反复调用filterKeys
是不可取的,因为它会在其上堆叠更多的视图。
但是,使用filter
的解决方案仍应该有效。
val updatedCache = cache -- Set("x", "y", "b")
- Alex在地图上进行大量过滤最终会导致结果地图变得过慢。因为您需要在到达实际缓存存储之前应用所有添加的过滤器。我建议使用--
语法从地图中删除元素。
scala> Map("a" -> 1, "b" -> 2, "c" -> 3)
res0: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2, c -> 3)
scala> res0 -- Set("x", "y", "b")
res1: scala.collection.immutable.Map[String,Int] = Map(a -> 1, c -> 3)
filter
"返回一个新的可遍历集合,该集合由满足给定谓词 p 的此可遍历集合的所有元素组成。元素的顺序被保留。"(强调我的) - Andrey Tyukinfilters
是原始集合的包装器。这有助于节省一些内存,因为您不必复制整个映射,但最终您的映射将变得非常缓慢。自己试试吧。 - Alexfilter
的工作方式就像你说的那样。但是 filterKeys
会将所有内容都包装在一个 Filter 包装器中,所以 filterKeys
最终会变慢,而不是 filter
。 - Alexfilter
的说法在2.12.4中是无法复现的。如果我定义了val m = ((0 to 100) zip (400 to 5000)).toMap; val n = m.filter{ case (k, _) => k % 2 == 0 }
,然后展示m.getClass
和n.getClass
,我会得到scala.collection.immutable.HashMap$HashTrieMap
。如果你的Scala做了其他事情,你应该升级到更新的版本或提交一个错误报告。我正在看filterKeys
,我不经常使用它,也许我确实错过了什么。 - Andrey Tyukin也许是这样:
val it = Iterator.continually(hashMap.headOption).takeWhile(_.isDefined).flatten
for ((key, value) <- it) {
hashMap.remove(key)
... //do something here with value
}
其中hashMap
是一个可变的HashMap实例。
iter
是如何定义的? - Reimeuscache.filter{ case (k, _) => part.contains(k) }
过滤cache
呢? - Andrey Tyukinpart
中的元组。如果我没有漏掉什么,这就是您的迭代器循环所做的事情。请参见下面的可编译示例。 - Andrey Tyukincache
,应该坚持使用filter
,因为filterKeys
的行为会有很大不同(感谢 @SimY4 指出)。 - Andrey Tyukin