【问题标题】:Why `floorEntry` and other methods are not accessible in PatriciaTrie?为什么在 PatriciaTrie 中无法访问 `floorEntry` 和其他方法?
【发布时间】:2015-09-12 13:44:35
【问题描述】:

在实现 ip-lookup 结构时,我试图在类似 trie 的结构中维护一组键,允许我搜索键的“地板”(即小于或等于的最大键到给定的键)。我决定使用 Apache Collections 4 PatriciaTrie 但遗憾的是,我发现 floorEntry 和相关方法不是 public。我目前的“肮脏”解决方案是通过反射(在 Scala 中)强制它们:

val pt = new PatriciaTrie[String]()
val method = pt.getClass.getSuperclass.getDeclaredMethod("floorEntry", classOf[Object])
method.setAccessible(true)
// and then for retrieving the entry for floor(key) 
val entry = method.invoke(pt, key).asInstanceOf[Entry[String, String]]

是否有任何干净的方式来拥有相同的功能?为什么这些方法不公开?

【问题讨论】:

    标签: java scala reflection apache-commons-collection patricia-trie


    【解决方案1】:

    为什么这些方法不公开,我不知道。 (也许是因为你可以用通用的Map API 实现你想要的)。

    这是满足您要求的一种方法:

    PatriciaTrie<String> trie = new PatriciaTrie<>();
    trie.put("a", "a");
    trie.put("b", "b");
    trie.put("d", "d");
    
    String floorKey = trie.headMap("d").lastKey(); // d
    

    根据文档,这是非常有效的,因为它取决于树的最大密钥的位数。

    编辑:根据下面的评论,上面的代码有一个边界问题:headMap() 返回一个地图视图,其键严格低于给定钥匙。这意味着,即对于上述示例,trie.headMap("b").lastKey() 将返回 "a",而不是 "b"(根据需要)。

    为了解决这个边界问题,您可以使用以下技巧:

    String cFloorKey = trie.headMap("c" + "\uefff").lastKey(); // b
    
    String dFloorKey = trie.headMap("d" + "\uefff").lastKey(); // d
    

    现在一切正常,因为\uefff 是最高的 unicode 字符。实际上,搜索key + "\uefff",无论key 是什么,如果它属于trie,则始终返回key,或者如果key 不存在于trie 中,则始终返回key 之前的元素。

    现在,这个技巧适用于String 键,但也可以扩展到其他类型。即对于 Integer 键,您可以搜索 key + 1,对于 Date 键,您可以添加 1 毫秒等。

    【讨论】:

    • 如果我理解正确,trie.headMap(k).lastKey(); 不会返回 k 如果它已经包含在地图中,因为headMap 的文档说它 “返回一个视图此映射的部分,其键严格小于 toKey".
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2016-06-18
    • 2020-11-03
    • 2012-03-19
    相关资源
    最近更新 更多