5

我正在寻找一种SetJava 实现,它提供基于元素属性的查找。用 Guava 术语思考它可以使用 a Function<Element, SearchKey>(预计在所有集合元素中是唯一的)并提供一个find(SearchKey key)返回 an的方法Element,该函数将为其返回key

需要满足的明显假设:

  • 的结果在集合function(element)中的整个生命周期内是恒定的element
  • 函数为所有集合元素提供独特的结果

原因:
有时需要Set<Element>并且字段类型不能更改为 a Map<SearchKey, Element>(例如在 JPA 实体中或在第 4 方代码的情况下)。尽管如此,当构建这样一个对象时,人们可以安全地使用他们自己的Set具有类似Map功能的实现。

备择方案:

我已经找到了一些替代方案,但似乎都不完美

  • 没有Map类似功能 - 使用线性搜索find(SearchKey)实现(适用于每个Set实现:)
  • 使用TreeSetwith Comparatorcompare SearchKeys- 有点像hack,特别是这不再尊重元素相等性
    ,调用“find”方法ceiling并要求您Element为查找目的构建人工(呃......)
  • “等价集”(http://code.google.com/p/guava-libraries/issues/detail?id=576)-但这没有实现,似乎也不会

如果您想回答您不知道更多替代方案 - 节省您的时间并且不要。这是我已经知道的事情,我将无法接受您的回答。)

4

3 回答 3

3

我正在寻找 Java 中的 Set 实现,它提供基于元素属性的查找。

这就是 Map 的用途,是的,您确实需要构建一个关键对象来表示被查找的内容。

这是 Java 中最简单、更有效的解决方案,所以虽然有点不愉快,但我不会担心。

顺便说一句:集合通常被实现为 JRE 中地图上的一层,恕我直言,这不是理想的。

于 2013-08-22T06:13:10.797 回答
2

如果我正确理解您的问题,我会想到两种选择:

  1. 您的 hack 的一种变体: aTreeSet带有与 . 进行比较的比较YourSearchKeyYourElement。您可以欺骗类型系统,也可以创建一个通用接口YourAbstractSearchKey。唯一的缺点是:
    • YourSearchKey对象可以插入到Set. Collections.checkedSet()在这一点上可以提供帮助。
    • 搜索结果很可能需要转换为YourElement. 解决方法:在通用接口中定义所有属性,YourAbstractSearchKey并为额外的属性YourSearchKey抛出实现。UnsupportedOperationException
  2. 类似,但带有地图。您不需要添加额外的属性,YourAbstractSearchKey因为 Map 将是Map<YourAbstractSearchKey,YourElement>. 要添加元素,您需要编写myMap.put(newElement,newElement).
于 2013-08-22T06:28:22.370 回答
2

我一定错过了什么,否则很容易通过ForwardingSetto HashBiMap.keySet()。我的琐碎实现只关心addand addAll,所有其他东西都应该毫不费力地工作。没有单一的测试,我建议为此使用 Guava testlib。

于 2013-09-06T17:31:05.053 回答