在 Java 中获取唯一的集合元素对的习惯用法
是否有一个标准的习惯用法来获取给定集合中每个唯一元素对的集合?
就我们的目的而言,(a,b) 的集合相当于 (b,a),因此结果集中应该只有一个出现。
我可以看到如何使用基于配对元素实现 hashCode 和 equals() 的 Pair 类来构造这样的集合,但我想知道是否还没有更标准的方法来生成这样的集合。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
就像你说的,一个带有 hashcode 的 Pair 类equals 实施并放置在 HashSet 中将实现您正在寻找的内容。我不知道 JDK 数据结构本身可以执行此操作。
如果你想进一步概括它,你可以创建一个 Tuple,
Tuple
并基于该 Tuple 声明一个 HashSet,HashSet> ;
。然后为元组类型创建更通用的 Equals/Hashcode 方法。这是一个示例实现:
Like you said, a Pair class with hashcode & equals implemented and placed in a HashSet would accomplish what you are looking for. I am not aware of a JDK data structure that does this natively.
If you wanted to generalize it a little further, you could make a Tuple,
Tuple<T1,T2>
and declare a HashSet based on that Tuple,HashSet<Tuple<T1,T2>>
. Then create a more generic Equals/Hashcode method for the tuple types.Here is an example implementation:
我为您创建了一个“惰性”实现,更通用一些(即可以列出任何大小的子集)。
它是懒惰的,因为不需要同时在内存中存储原始集合(或所有子集)的所有元素,但它并不是真正高效:在迭代器上调用
next()
仍然可以意味着迭代原始集合k-1
次(如果k
是想要的子集大小) - 幸运的是不是每次,大多数时候我们只需要一个一个迭代器上的 next()
(至少当k
与基集的大小n
相比较小时)。当然,我们仍然需要在内存中保留子集的 k 个元素。我们还必须假设所有迭代器都使用相同的顺序,只要底层集合不改变(并且我们不希望它在迭代之一正在进行时发生改变)。如果 Iterator 接口允许克隆迭代器,即在第一个迭代器当前所在的位置启动第二个迭代器,那么这会容易得多。 (我们现在使用
scrollTo
方法实现这一点。)对于排序的地图,这应该更容易(等待那里的更新)。与往常一样,对于我在这里的更大的代码示例,这个 在我的 github 存储库 stackoverflow-examples 中也可以找到。
I have created a "lazy" implementation for you, a bit more general (i.e. can list subsets of any size).
It is lazy in the sense of not needing all elements of the original set (or all subsets) in memory at the same time, but it is not really efficient: invoking
next()
on the iterator still can mean iterating over the original setk-1
times (ifk
is the subset-size wanted) - luckily not every time, most times we only need a singlenext()
on one iterator (at least whenk
is small compared ton
, the size of the base set). And of course we still need to have thek
elements of the subset in memory.We also have to assume that all iterators use the same order, as long as the underlying set does not change (and we don't want it to change while one of our iterations is in progress). This would be much easier if the
Iterator
interface allowed cloning an iterator, i.e. starting a second iterator at the point one iterator currently is. (We implement this now with thescrollTo
method.) For sorted Maps this should be much easier (await an update there).As always for my bigger code examples here, this is findable in my github repository stackoverflow-examples, too.