黑马程序员_关于纠结接口Comparator的实现方法compare(Object o1,Object o2)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?------- android培训、java培训、期待与您交流! ----------
?
今天在黑马论坛游街着一位同学的问题让我纠结了好久好久。
?
说起来想法也非常简单,看下面代码,
package com.itheima;import java.util.ArrayList;import java.util.Comparator;import java.util.Iterator;import java.util.List;import java.util.TreeSet;class test { public static void main(String[] args) { TreeSet ts = new TreeSet(new Demo2013()); ts.add("f8"); ts.add("25d55"); ts.add("1d1"); ts.add("8d56"); ts.add("25555"); ts.add("8d56"); System.out.println(ts); }}class Demo2013 implements Comparator { public int compare(Object o1,Object o2) { String s1 =(String)o1; String s2 =(String)o2; System.out.println(s1+"---"+s2);//用于研究 if (s1.length() > s2.length()) { return 1; } if (s1.equals(s2)) { System.out.println(s1+"+++"+s2); return 0; } return -1; }}?compare的方法是让这个ts里面的数据按照长度来排序,这个没问题,但是这位同学要在compare里面打印出相同的元素。
所以当s1和s2相同时,打印结果是
?
f8+++f8
8d56+++8d56
?
?
?
我试了很久,主要集中在如何删除f8.这第一个元素,不知道为什么这个compare在比较的时候,第一次一定是o1和o2一定都要取f8.我想这是java设计者的要求,一定会同时取ts里面的第一个元素。最后我是没找到办法的,但是我倒是发现了compare排序机制里面的一些问题,return 1和-1我之前就知道怎么回事,return 0会如何呢?return 0的话会删除s1或者s2.因为它认为s1和s2是重复的。
?
后来我加入了 System.out.println(s1+"---"+s2);//用于研究 这段代码会,打印结果
?
f8---f8
f8+++f8
25d55---f8
1d1---f8
1d1---25d55
8d56---1d1
8d56---25d55
25555---1d1
25555---25d55
25555---8d56
8d56---1d1
8d56---25555
8d56---8d56
8d56+++8d56
?
我就看这个o1和o2的取法规律,虽然没有完全理清楚,但是再结合java对compare的说明
?
:
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
?
In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.
?
The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)
?
The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
?
Finally, the implementor must ensure that compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.
?
It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."
?
Specified by: compare(...) in Comparator
Parameters:
o1 the first object to be compared.
o2 the second object to be compared.
Returns:
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
?
上面这段英文总结起来说明一个问题,这个比较是传递的。类似于x>y,y>z.那么x>z。反正这个compare函数内部有这样一个机制。
最终:我大概总结了这个compare的算法。
我猜想有2个集合。第一个装着传进来的treeset数据,第二个是空的。以本代码为例
?
之后开始比较:
1、先把第一个集合里的第一个f8,放到第二个集合里面的第一个位置.之后就是我困惑的地方。(下述)
2、取第一个集合里面的下一个o1=25d55,再取第二个集合里面的第一个o2=f8。比较之后return 1,所以25d55放在f8后面且放入第二个集合的下一个位置
?
3、取第一个集合里面的下一个o1=1d1,再取第二个集合里面的第一个o2=f8,return 1.所以1d1放在f8后面,接着再取第二个集合里面的第二个o2=25d55,return -1.所以1d1放在25d55的后面。
?
其余类似。
?
最后,当o1==8d56和o2==8d56,两者一比较发现return 0了,那么不就把o1放进第二个集合。最后返回的第二个我觉得去不去集合就少了一个重复的元素。
?
我就想不通,第一步,为什么还要o1和o2还要取一次f8,在我没有添加return0的时候,集合里只有一个f8,添加了之后还是只有一个f8.如何判断机制和8d56那一步一样,那么在没有return 0的时候,应该是有2个f8.
?
我又想到了一种解释,就是o1和o2如果相同的话,就让o1放在o2的位置,这样集合2中还是没有重复元素。关键是return 0的存在与否不影响f8,但是却影响着8d56啊。
?
?
算了,这个问题想了太久了,不纠结了,这次博客记录在这里,以后再回答吧
?
?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------- android培训、java培训、期待与您交流! ----------