implementing compareTo method for several fields

后端 未结 4 1825
自闭症患者
自闭症患者 2021-02-11 10:51

I want to compare two object based on 5-tuple which are: srcAddr, dstAddr, srcPort, dstPort, protocol

here is what i have:

public class Flows implements          


        
相关标签:
4条回答
  • 2021-02-11 11:21

    You can write like this also, I have done like this in my project

    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;
                    }
                }
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2021-02-11 11:32

    Use string.equals() instead of ==.

    0 讨论(0)
  • 2021-02-11 11:33

    The compiler / code checker is warning you that comparing String values with == is almost always a mistake.

    But fixing that won't really help because your code does nothing like what a correctly implemented compareTo method should do.

    A straight-forward implementation of compareTo for your Flows class would be:

    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);
    }
    

    That assumes the the fields are never null. If they are, then write a safeCompare(String, String) method that takes care with nulls and apply it to each field as above.

    EDIT

    Given that you are defining compareTo you also ought to declare equals and hashCode to be consistent with them. Otherwise certain collection methods are likely to behave incorrectly.

    EDIT 2

    The compiler error you mention in a comment on how to override compareTo method happens because the int compareTo(Flow flow) method actually implements the compareTo method of Comparable<Flow>. If you are going to declare Flow as implementing the raw interface type Comparable then the signature needs to be

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

    But a better solution would be to change the class declaration to:

    public class Flows implements Serializable, Comparable<Flow> {
    ...
    
    0 讨论(0)
  • 2021-02-11 11:44

    Try:

    @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();
    }
    

    Requires Guava

    0 讨论(0)
提交回复
热议问题