【问题标题】:Filter a MultiMap<Predicate, value>过滤 MultiMap<Predicate, value>
【发布时间】:2015-01-12 11:36:09
【问题描述】:

Block 是一些代表类型的长期存在的实例,例如Minecraft BlockType 草、green_wool 等。

我正在尝试找到一个 DataStructure 可以有效地存储和测试给定的 BlockPattern(如果您熟悉 Minecraft,可以考虑像黑曜石门户、Wither 等)但如果您不熟悉,则能够创建一个可以测试给定结构的类,该结构是由相对于所放置块的给定 Vector3i 处的块构建的。

Vector3i 表示给定谓词可以匹配的“块模式”中位置的整数向量。

例如你可以有一个谓词来测试任意块属性“热度”,以测试火和熔岩的真实性。

所以与其每次扫描整个模式以确保世界中的块位置,匹配谓词,我正在考虑扭转问题。

缓存一个方块在多图模式中的潜在位置,并获取所有潜在位置,以限制之后发生的检查量。

所以我有一个Multimap&lt;Predicate&lt;Block&gt;,Vector3i&gt; patternLookup 缓存。

这表示允许在 BlockPattern 中找到一个块的潜在位置。

所以玩家放置了一个方块,我需要过滤多重地图,收集方块被“允许”(谓词为真)存在的所有可能位置。

但是,作为优化步骤,我认为只测试可能匹配的谓词(就身份而言)可能会更快。 (三年后我不确定这个假设是否正确)

如何使用 guava 的功能特性过滤多图的内容以获取值的集合? (或者我最好只是迭代EntrySet?)

例如

【问题讨论】:

  • 当然,遍历 entrySet,但是为什么你首先要在 Predicate 上键入 Multimap
  • 我提供了一个 API,因此另一个应用程序可以提供谓词来匹配 3d 体素数组,通过允许它们提供谓词来匹配他们需要的任何东西。我将提供的谓词作为优化措施,所以我只需要检查匹配的向量并返回重要的结果。 github.com/ryantheleach/MemoryStones-Sponge/blob/master/src/…
  • 是的,没有比迭代entries()asMap().entrySet() 更好的选择了,具体取决于您想要的输出格式。

标签: java filter functional-programming guava predicates


【解决方案1】:

可以使用Multimaps.filterEntries(),类似:

public static <V> Multimap<Predicate<V>, V> filterByPredicateKey(
    Multimap<Predicate<V>, V> multimap) {
  return Multimaps.filterEntries(multimap, e -> e.getKey().apply(e.getValue()));
}

这与您在问题中提到的多映射类型签名不太匹配,但我认为 blockVector3i 在某种程度上是相关的,否则您无论如何都无法将谓词应用于值。

这将返回支持多图的视图,该视图是免费的 (O(1)) 可构建但在访问时应用过滤,因此返回的多图上的 .get() O(n)。根据预期的用例,您可能更愿意将此多映射复制到单独的不可变多映射中,这样过滤只会发生一次。

【讨论】:

  • 那是通过应用于值的键来过滤地图,对吧?已经有几年了,但我当时想做的是优化大面积 Minecraft 块的查找/扫描。在这种情况下,块是一个单例,表示块的轻量级状态,向量是第一次测试谓词时找到块的位置。所以我试图使用无副作用谓词的身份来节省多次扫描同一区域的时间。
  • 那么,multimap 所键入的谓词不是用来过滤条目的吗?您尝试进行哪种过滤?
  • 我认为向 filterByPredicateKey 添加一个块参数并执行 e.getKey().apply(block) 会过滤集合,只返回谓词为真的结果,这接近我的要求.但已经很久了,我不确定我在问什么。
猜你喜欢
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多