Reputation: 5374
Am somewhat confused with Java's compareTo() and Collections.sort() behavior.
I am supposed to sort a column in ascending order using compareTo() & Collections.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...
Upvotes: 2
Views: 6126
Reputation: 32004
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.
Upvotes: 2
Reputation: 110054
To address your specific questions:
comparison
variable at all.Comparable
, no need to deal with a Comparator
. It's for when you need to compare something that isn't Comparable
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();
}
Upvotes: 3
Reputation: 54806
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
, but compareTo()
works just as well. In either case, your code would look pretty much the same.
Upvotes: 0
Reputation: 28568
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.
Upvotes: 0