Reputation: 29
I have to sort an arraylist by the date and time entered by the user but for some reason the output comes out not in order
Below this code it the code im using to order
public int compareTo(Vehicle v){
int returnValue = 0;
if (this.parkDate.year> v.parkDate.getYear() &&
this.parkDate.month> v.parkDate.getMonth() &&
this.parkDate.day> v.parkDate.getDay() &&
this.parkDate.hours> v.parkDate.getHours() &&
this.parkDate.minuets> v.parkDate.getMinuets()){
returnValue = 1; }
else
returnValue = - 1;
return returnValue;
}
Upvotes: 0
Views: 94
Reputation: 12817
Instead of storing the date and time as primitives, you can create a LocalDateTime
and use it in Comparator
add field parkDate
as LocalDateTime
in Vehicle
class
LocalDateTime parkDate = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);
use the parkDate
in compareTo
method
@Override
public int compareTo(Vehicle o) {
return this.parkDate.compareTo(o.parkDate);
}
Upvotes: 0
Reputation: 792
i think you can use "compareTo" the result is 0, 1, -1
public int compareTo(Vehicle a, Vehicle b){
return a.parkDate.compareTo(b.parkDate);
}
Upvotes: 0
Reputation: 7326
The reason is because you have an error in your boolean logic.
if (this.parkDate.year> v.parkDate.getYear() &&
this.parkDate.month> v.parkDate.getMonth() &&
this.parkDate.day> v.parkDate.getDay() &&
this.parkDate.hours> v.parkDate.getHours() &&
this.parkDate.minuets> v.parkDate.getMinuets()){
returnValue = 1; }
else
returnValue = - 1;
Else is like taking the negation of your if
statement. In this case that equates to the following:
this.parkDate.year <= v.parkDate.getYear()
OR
this.parkDate.month <= v.parkDate.getMonth()
OR
this.parkDate.day> v.parkDate.getDay()
...
In other words
Negation(A && B) <=> (Negation(A) || Negation(B))
In the context of your situation, your else
logic could be true even if the year is greater than this.parkDate
I think this should be enough to help you get it right. :)
Upvotes: 0
Reputation: 201447
Your comparison logic isn't correct. You might perform your comparisons with Integer.compare(int, int)
and return
the result in the case of non-zero. Something like,
public int compareTo(Vehicle v) {
int returnValue = Integer.compare(this.parkDate.getYear(),
v.parkDate.getYear());
if (returnValue != 0) {
return returnValue;
}
returnValue = Integer.compare(this.parkDate.getMonth(),
v.parkDate.getMonth());
if (returnValue != 0) {
return returnValue;
}
returnValue = Integer.compare(this.parkDate.getDay(),
v.parkDate.getDay());
if (returnValue != 0) {
return returnValue;
}
returnValue = Integer.compare(this.parkDate.getHours(),
v.parkDate.getHours());
if (returnValue != 0) {
return returnValue;
}
return Integer.compare(this.parkDate.getMinuets(),
v.parkDate.getMinuets());
}
Or, you could shorten the above by using arrays and something like
int[] a = { this.parkDate.getYear(), this.parkDate.getMonth(),
this.parkDate.getDay(), this.parkDate.getHours(),
this.parkDate.getMinuets() };
int[] b = { v.parkDate.getYear(), v.parkDate.getMonth(),
v.parkDate.getDay(), v.parkDate.getHours(),
v.parkDate.getMinuets() };
for (int i = 0; i < a.length; i++) {
int rv = Integer.compare(a[i], b[i]);
if (rv != 0) {
return rv;
}
}
return 0;
Finally, I believe you want minutes not minuets.
Upvotes: 2
Reputation: 11975
The primary issue is your comparison logic. You are testing that your vehicle's park date's year is greater than the other vehicle's park date's year and your vehicle's park date's month is greater than the other vehicle's park date's month and ditto for the day, hour and minute. This is incorrect.
Consider 2016-01-01 00:00
and 2015-12-31 23:59
. The former clearly comes after the latter, but its month, day, hour and minute are all less than the other. Your logic would therefore fail to produce the correct result in this instance.
A more suitable approach would be to:
(Also, make sure you remembered to implement Comparable
on your Vehicle
class.)
Upvotes: 0