为几个字段实现compareTo方法

Red*_*ion 0 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;
}
Run Code Online (Sandbox Code Playgroud)

}

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

Ste*_*n C 12

编译器/代码检查器警告您,比较String值==几乎总是一个错误.

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

compareToFlows班级的直接实施将是:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

编辑

鉴于你的定义compareTo你也应该声明equalshashCode与它们保持一致.否则,某些收集方法可能行为不正确.

编辑2

您在评论如何覆盖compareTo方法时提到的编译器错误发生,因为该int compareTo(Flow flow)方法实际上实现了compareTo方法Comparable<Flow>.如果您要声明Flow为实现原始接口类型,Comparable那么签名需要

public int compareTo(Object obj) {
    Flow flow = (Flow) obj;
    ...
Run Code Online (Sandbox Code Playgroud)

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

public class Flows implements Serializable, Comparable<Flow> {
...
Run Code Online (Sandbox Code Playgroud)


whi*_*rra 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();
}
Run Code Online (Sandbox Code Playgroud)

需要番石榴