compareTo() and Collections.sort() Solution For Multiple Column Ordering (Ascending) question
Am somewhat confused with Java's compareTo() and Collections.sort() behavior.
I am supposed to sort a column in ascending order using compareTo() & Collectio开发者_StackOverflow社区ns.sort().
My criteria is (if the same number occurs than please sort the next available column).
(1) Document Number (2) Posting Date (3) Transaction Date (4) Transaction Reference Number Comparison
Here's the code (which is executed in a calling method) that implements the Collection.sort() method:
public int compareTo(CreditCardTransactionDetail t) {
int comparison = 0;
int documentNumberComparison = this.getDocumentNumber().compareTo(t.getDocumentNumber());
if (documentNumberComparison != 0) {
comparison = documentNumberComparison;
}
else {
int postingDateComparison = this.getTransactionPostingDate().compareTo(t.getTransactionPostingDate());
if (postingDateComparison != 0) {
comparison = postingDateComparison;
}
else {
int transactionDateComparison = this.getTransactionDate().compareTo(t.getTransactionDate());
if (transactionDateComparison != 0) {
comparison = transactionDateComparison;
}
else {
int transactionRefNumberComparison = this.getTransactionReferenceNumber().compareTo(t.getTransactionReferenceNumber());
LOG.info("\n\n\t\ttransactionRefNumberComparison = " + transactionRefNumberComparison + "\n\n");
if (transactionRefNumberComparison != 0) {
comparison = transactionRefNumberComparison;
}
}
}
return comparison;
}
Question(s):
(1) Am I doing the right thing? When a comparison = 0, it returns as -2. Is this correct behavior because I always thought it to be between -1,0,1.
(2) Should I be using the comparator?
Happy programming...
To address your specific questions:
- Yes, that looks fine. The result does not have to be -1, 0 or 1. Your code could be slightly less verbose, though, and just return as soon as it finds a result without using the
comparison
variable at all. - If you're implementing
Comparable
, no need to deal with aComparator
. It's for when you need to compare something that isn'tComparable
or need to compare in a different way.
Guava's ComparisonChain class makes a compareTo
method like this incredibly easy:
public int compareTo(CreditCardTransactionDetail o) {
return ComparisonChain.start()
.compare(getDocumentNumber(), o.getDocumentNumber())
.compare(getTransactionPostingDate(), o.getTransactionPostingDate())
.compare(getTransactionDate(), o.getTransactionDate())
.compare(getTransactionReferenceNumber(), o.getTransactionReferenceNumber())
.result();
}
Answer for (1): It's correct. see javadoc of Comparator.compare(T, T): "a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second."
Or use Google Guava which encapsulates Comparator for easier and powerful usage:
//Write 4 Comparators for each comparable field
Ordering ordering = Ordering.from(comparatorDocumentNumber)
.compound(comparatorTransactionPostingDate)
.compound(comparatorTransactionDate)
.compound(comparatorTransactionReferenceNumber);
Collections.sort(list, ordering);
It decouples each Comparator, it's easy to change/ add/ remove fields order. EDIT: see ColinD's lighter solution.
Your compareTo is reasonable enough. compareTo can return values other than -1,0,1. Just negative, 0 and positive.
You should be using a comparator.
According to the Comparable Documentation,
compareTo()
:Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
So -2 is a valid result.
That's a matter of preference, really. Personally I prefer using a
Comparator
, butcompareTo()
works just as well. In either case, your code would look pretty much the same.
精彩评论