为几个字段实现compareTo方法

时间:2010-08-10 14:02:35

标签: java

我想比较基于5元组的两个对象: srcAddr,dstAddr,srcPort,dstPort,protocol

这就是我所拥有的:

public class Flows implements Serializable, Comparable {

String srcAddr, dstAddr, srcPort, dstPort, protocol;

public int compareTo(Flows arg0) {
    if(this.srcAddr == arg0.srcAddr &&
        this.dstAddr == arg0.dstAddr &&
            this.srcPort == arg0.srcPort &&
                this.dstPort == arg0.dstPort &&
                    this.protocol == arg0.protocol)
                        return 0;
}

}

但它不起作用。它说无法比较两个字符串。 谁能帮我理解是什么问题? 感谢。

4 个答案:

答案 0 :(得分:12)

编译器/代码检查器警告您将String值与==进行比较几乎总是错误。

但是修复它并不会真正有用,因为你的代码没有像正确实现的compareTo方法那样做。

compareTo课程的Flows的直接实施将是:

public int compareTo(Flows other) {
    int res = this.srcAddr.compareTo(other.srcAddr);
    if (res != 0) {
        return res;
    }
    res = this.dstAddr.compareTo(other.dstAddr);
    if (res != 0) {
        return res;
    }
    res = this.srcPort.compareTo(other.srcPort);
    if (res != 0) {
        return res;
    }
    res = this.dstPort.compareTo(other.dstPort);
    if (res != 0) {
        return res;
    }
    return this.protocol.compareTo(other.protocol);
}

假设字段永远不为空。如果是,则编写一个safeCompare(String, String)方法来处理空值并将其应用于每个字段,如上所述。

修改

鉴于您要定义compareTo,您还应声明equalshashCode与它们一致。否则,某些收集方法的行为可能不正确。

编辑2

您在how to override compareTo method的评论中提到的编译器错误是因为int compareTo(Flow flow)方法实际实现了Comparable<Flow>的compareTo方法。如果您要将Flow声明为实现原始接口类型Comparable,那么签名必须是

public int compareTo(Object obj) {
    Flow flow = (Flow) obj;
    ...

但更好的解决方案是将类声明更改为:

public class Flows implements Serializable, Comparable<Flow> {
...

答案 1 :(得分:5)

尝试:

@Override
public int compareTo(final Flows that) {
    return ComparisonChain.start().
        compare(this.srcAddr, that.srcAddr).
        compare(this.dstAddr, that.dstAddr).
        compare(this.srcPort, that.srcPort).
        compare(this.dstPort, that.dstPort).
        compare(this.protocol, that.protocol).
        result();
}

需要Guava

答案 2 :(得分:2)

使用string.equals()代替==。

答案 3 :(得分:0)

你也可以这样写,我在我的项目中这样做了

public int compareTo(Flows arg0) {
    int comp1, comp2, comp3, comp4;
    comp1 = this.srcAddr.compareTo(arg0.srcAddr);
    comp2 = this.dstAddr.compareTo(arg0.dstAddr);
    comp3 = this.srcPort.compareTo(arg0.srcPort);
    comp4 = this.protocol.compareTo(arg0.protocol);

    if (comp1 == 0 && comp2 == 0 && comp3 == 0 && comp4 == 0) {
        return 0;
    } else {

        if (comp1 != 0)
            return comp1;
        else {
            if (comp2 != 0)
                return comp2;
            else {
                if (comp3 != 0)
                    return comp3;
                else {
                    if (comp4 != 0)
                        return comp4;
                    else
                        return 0;
                }
            }
        }

    }

}