CompareTo 可能返回 0,替代 TreeSet/TreeMap
我需要一组已排序的对象,目前正在使用 TreeSet
。我的问题是对象的 compareTo
通常会返回 0
,这意味着这两个对象的顺序保持不变。 TreeMap
(默认情况下由 TreeSet
使用)会将它们视为同一个对象,但事实并非如此。
我可以使用什么替代TreeMap
?
用例:我有一组可显示对象。我想按 Y 坐标对它们进行排序,以便它们以正确的顺序呈现。当然,两个对象很可能具有相同的 Y 坐标。
I need a sorted set of objects and am currently using the TreeSet
. My problem is that the compareTo
of the objects will often return 0
, meaning the order of those two objects is to be left unchanged. TreeMap
(used by TreeSet
by default) will then regard them as the same object, which is not true.
What alternative to TreeMap
can I use?
Use case: I have a set of displayable objects. I want to sort them by Y coordinate, so that they are rendered in the correct order. Of course, two objects may well have the same Y coordinate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您正在定义一个要比较的标准,但您需要添加额外的标准。
你说:
那么,如果两个元素具有相同的 Y 坐标,您首先放置什么?其他标准是什么?
它可能是创建时间,也可能是 x 坐标,您只需定义它:
您必须定义一个
Thing
何时高于/低于/等于/高于其他Thing .如果其中一个属性与其他属性相同,您可能不应该移动它们。如果有其他属性可以比较,就使用它。
You're defining one criteria to compare, but you need to add extra criteria.
You say:
So, If two elements have the same Y coordinate, what you you put first? What would be the other criteria?
It may be the creation time, it may be the x coordinate, you just have to define it:
You have to define when one
Thing
is higher / lower / equal / than otherThing
. If one of the attributes is the same as other, probably you should not move them. If is there other attribute to compare the use it.您遇到的问题是
compareTo
返回0
意味着对象相等。同时,您将它们放入一个集合中,该集合不允许相同元素的多个副本。要么重写您的compareTo,以便不相等的元素返回不同的值,要么使用类似于java.util.PriorityQueue的东西,它允许相等元素的多个副本。
The issue you're running into is that
compareTo
returning0
means that the objects are equal. At the same time, you're putting them into a set, which does not allow multiple copies of equal elements.Either re-write your
compareTo
so that unequal elements return different values, or use something like ajava.util.PriorityQueue
which allows multiple copies of equal elements.我以前做过这个。它是一个有序的多重映射,它只是一个 List 对象的 TreeMap。像这样......
每次引入新键时,您都需要构造一个新的 LinkedList,因此将其包装在自定义容器类中可能会有所帮助。我会尝试找到一些东西。
因此,我快速地将这个自定义容器放在一起(完全未经测试),但这可能就是您正在寻找的。请记住,只有当您确实正在寻找值列表的有序映射时,才应该使用这种类型的容器。如果您的值存在某种自然顺序,您应该像其他人建议的那样使用 TreeSet。
这是一个基本测试:
输出如下:
I've done this before. It's an ordered multi-map and it is just a TreeMap of List objects. Like this..
You need to construct a new LinkedList every time a new key is introduced, so it might be helpful to wrap it in a custom container class. I'll try to find something.
So, I threw this custom container together quickly (completely untested), but it might be what you are looking for. Keep in mind that you should only use this type of container if you are truly looking for an ordered map of value lists. If there is some natural order to your values, you should use a TreeSet as others have suggested.
Here's a rudimentary test:
The output is this:
我有自己的一个想法,但这更多的是一种解决方法
I have one idea of my own, but it's more of a workaround
使用排序集(例如 TreeSet)时需要记住两件重要的事情:
1)它们是集合;同一集合中不允许有两个相等的元素
2) 相等必须与比较机制一致(比较器或可比较)
因此,在您的情况下,您应该通过添加一些辅助排序标准来“打破联系”。例如:首先使用 Y 轴,然后是 X 轴,然后是一些唯一的对象标识符。
另请参阅 http://eyalsch.wordpress.com/2009/11/23/comparators /
There are 2 important things to remember when using sorted sets (e.g. TreeSet) :
1) They are sets; two equal elements are not allowed in the same collection
2) Equality must be consistent with the comparison mechanism (either comparator or comparable)
Therefore, in your case you should "break ties" by adding some secondary ordering criteria. For example: first use Y axis, then X, and then some unique object identifier.
See also http://eyalsch.wordpress.com/2009/11/23/comparators/