0

我需要为 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);
4

3 回答 3

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) ));
于 2012-12-14T11:34:54.623 回答
1

对于较大的时间差异,这将产生令人惊讶的结果。compare 应该只返回 -1、0 或 +1,但您可以使用更大的范围。因为long您希望将溢出转换为具有意外行为的 int。

我建议你使用Long.compare()它是否可用,Double.compare如果它不可用。

顺便说一句,由于地图不允许重复键,当您返回 0 时,它会将其视为重复项,因此如果您有a:1b:1并且c:1它们都是重复项。解决此问题的方法是在比较相等的情况下比较整个字符串。

BTW2 虽然这是非常低效的代码,但您可以使用parseLong而不是valueOf稍微改进它。

于 2012-12-14T11:36:48.603 回答
1

除了错字之外,请注意您有 2 个潜在的溢出源:减去 2 个 long 和转换为 int 时。使用它可能会更好:

Long value1 = Long.valueOf(k1.substring(k1.indexOf(":")+1));
Long value2 = Long.valueOf(k2.substring(k2.indexOf(":")+1));
return value1.compareTo(value2);
于 2012-12-14T11:37:37.100 回答