logical inconsistence between Set and SortedSet interfaces in Java [closed]

萝らか妹 提交于 2019-12-31 00:44:16

问题


I noticed a logical inconsistence between Set and SortedSet interfaces in Java.

SortedSet recognizes different objects (by equal() method) as equals if they are the same during the comparison, but it is logically incorrect. Comparing of objects should be responsible only for order of objects.

For example: I can have many products and I want to sort them by price. In this case the SortedSet can’t contain different products with the same price: [“salt”,0.5$], [“milk”, 1$], [“bread”, 1$], [“bananas”, 2$] In example above milk will be replaced by bread. In this case the contract of inherited Set interface will be violated, because unequals objects replace each other. I red JavaDoc of SortedSet and know that this behavior well documented, but I think it is a logical failure.

What is your opinion, maybe you have already similar problems with Set and SortedSet?


回答1:


It is not a logical failure but a property by design. Note that if your comparison algorithm is consistent with equals, a.compareTo(b) == 0 will be equivalent to a.equals(b).

The javadoc is actually very explicit about it:

The behavior of a sorted set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

Is that useful?

That actually gives flexibility where you want to reach a specific behaviour. Let's say for example that you want to put strings in your SortedSet and have them sorted ignoring the case, you can use:

Set<String> set = new TreeSet<> (String.CASE_INSENSITIVE_ORDER);

That will achieve the expected result, but this:

set.add("ABC");
set.add("abc");

will only add one string to your set because they will be deemed equal with that specific comparator.




回答2:


You probably mean the equals() method which is actually available in Object, so every single object type in Java either overrides it or inherits it from Object.




回答3:


In Java, generally speaking, two objects a and b are the same if a.equals(b) == true. And a Set, every Set, even SortedSet, has no duplicates, so if you override equals to compare price property, two objects are the same if they have the same price.

I guess you don't override equals method but provide a Comparator to SortedSet to make the ordering. In this case, as said in another answer, if a.compareTo(b) == 0 will be equivalent to a.equals(b).

If you want to order that Set, what you need is another structure, like a List to make the ordering. Something like:

List<Product> list = new ArrayList<Product>(myUnorderedProductsSet);
Collections.sort(list, comparatorByPrice);

Notice that this doesn't gonna double or copy your Product Beans, just would be another structure with references to the same objects in different order. So is not something expensive or avoidable.



来源:https://stackoverflow.com/questions/14534713/logical-inconsistence-between-set-and-sortedset-interfaces-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!