我需要为ConcurrentSkipListMap定义一个自定义比较器,我使用此代码根据'LogicalClock'进行排序,但结果并不像我预期的那样。我创建了这样的密钥:“ClientId”+“:”+“LogicalClock”
class Qentry{
int AckCount;
int ClientID;
long LogicalClock;
}
Comparator<String> LogicalClockComparator = new Comparator<String>() {
@Override public int compare(String k1, String k2) {
if (k1.compareTo(k2)==0)
return 0;
return (int)( Long.valueOf(k1.substring(k1.indexOf(":")+1)) -Long.valueOf(k2.substring(k1.indexOf(":")+1) ));
}
ConcurrentSkipListMap<String,Qentry> q;
q =new ConcurrentSkipListMap<String,Qentry>(LogicalClockComparator);
答案 0 :(得分:2)
看起来像是一个错字(或复制/粘贴错误)给我,也许你想用(看看行尾)
return (int)( Long.valueOf(k1.substring(k1.indexOf(":")+1)) -Long.valueOf(k2.substring(k2.indexOf(":")+1) ));
而不是你拥有的:
return (int)( Long.valueOf(k1.substring(k1.indexOf(":")+1)) -Long.valueOf(k2.substring(k1.indexOf(":")+1) ));
答案 1 :(得分:1)
对于大的时间差异,这会产生令人惊讶的结果。 compare应该只返回-1,0或+1,但你可以使用更大的范围。对于long
,您希望将溢出转换为int,这会产生意外行为。
我建议您使用Long.compare()
(如果可用)和Double.compare
(如果不可用)。
BTW,因为地图不允许重复键,当您返回0时,它会将其视为重复,因此如果您有a:1
,b:1
和c:1
,则它们都是重复。解决这个问题的方法是在比较相等的情况下比较整个String。
BTW2虽然这是非常低效的代码,但您可以使用parseLong
代替valueOf
来稍微改进它。
答案 2 :(得分:1)
除了拼写错误之外,请注意您有两个潜在的溢出源:减去2个长点和转换为int时。最好使用:
Long value1 = Long.valueOf(k1.substring(k1.indexOf(":")+1));
Long value2 = Long.valueOf(k2.substring(k2.indexOf(":")+1));
return value1.compareTo(value2);