Alex Burrows
Alex Burrows

Reputation: 29

Sorting an arrayList

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

Here is the output message

Upvotes: 0

Views: 94

Answers (5)

Saravana
Saravana

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

HuntsMan
HuntsMan

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

Brian
Brian

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

Elliott Frisch
Elliott Frisch

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

dave
dave

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:

  • compare the years: if they are different you can return a result, ie. less than or greater than
  • if they are the same, compare the months; if they are different you can return a result
  • if they are the same, compare the days; if they are different you can return a result
  • if they are the same, compare the hours; if they are different you can return a result
  • if they are the same, compare the minutes; if they are different you can return a result
  • if they are the same, indicate the dates are equal

(Also, make sure you remembered to implement Comparable on your Vehicle class.)

Upvotes: 0

Related Questions