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 Serializable, Comparable {
String sr开发者_开发知识库cAddr, 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;
}
}
But it doesn't work. It says can not compare two strings. Can anyone help me to know what is the problem? Thanks.
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> {
...
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
Use string.equals()
instead of ==.
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;
}
}
}
}
}
精彩评论