Alex Lord Mordor
Alex Lord Mordor

Reputation: 3040

Java Object Comparable using many attributes

I have some orders to be loaded and unloaded in delivery routes, one route can have one OrderDocument asigned to it to be loaded, unloaded or both. Each order-document is ordered by an index in the route assigned. So the class looks like this:

class OrderDocument implements Comparable<ModelTask>{
    int order_id;  // The document ID
    int route_load_id;  // The route this order is assigned to be loaded
    int route_unload_id;  // The route this order is assigned to be loaded, may be same as route_load_id and viceversa
    int route_load_index;  // The index order in load route
    int route_unload_index;  // The index order in unload route
}

Then I have the Route class:

class Route{
    int id; // ID of route, this value should be in OrderDocument.route_load/unload_id
    ArrayList<OrderDocument> orders;  // **I WANT TO SORT THIS LIST**
   ...

So, I have a function that create a Route instance and adds OrderDocument objects to its orders ArrayList so the List should have Documents that Route.id is in route_load_id or in route_unload_id

The main problem

I need this list to be sorted by load/unload index if the route id is in load_id or unload_id. Actually I have the following Comparator aproach but is not working.

private class OrdersComparable implements Comparator<OrderDocument>{
    @Override
    public int compare(OrderDocument x, OrderDocument y) {
        if (x.route_load_id == y.route_load_id)
            return x.route_load_index - y.route_load_index;
        else if (x.route_load_id == y.route_unload_id)
            return x.route_load_index - y.route_unload_index;
        else if (x.route_unload_id == y.route_load_id)
            return x.route_unload_index - y.route_load_index;
        else if (x.route_unload_id == y.route_unload_id)
            return x.route_unload_index - y.route_unload_index;
        else
            return 0;
    }
}

Example

4 Orders in the Route-43, 2 to be loaded, 4 to be unloaded.

OrderDocument('order_id':1, 'route_load_id':43, 'route_unload_id':null, 'route_load_index':0, 'route_unload_index':null)
OrderDocument('order_id':2, 'route_load_id':43, 'route_unload_id':null, 'route_load_index':2, 'route_unload_index':null)
OrderDocument('order_id':3, 'route_load_id':null, 'route_unload_id':43, 'route_load_index':null, 'route_unload_index':1)
OrderDocument('order_id':1, 'route_load_id':null, 'route_unload_id':43, 'route_load_index':null, 'route_unload_index':3)

Actual order by order_id: 1, 2, 3, 1

Required order by order_id: 1, 3, 2, 1

Upvotes: 0

Views: 53

Answers (1)

y.luis.rojo
y.luis.rojo

Reputation: 1824

If you are using null values (and the nullable corresponding types), you have to check your conditions do not compare nulls, otherwise will satisfy a nondesirable condition:

class OrderDocument implements Comparable<ModelTask> {
    int order_id;  // The document ID
    Integer route_load_id;  // The route this order is assigned to be loaded
    Integer route_unload_id;  // The route this order is assigned to be loaded, may be same as route_load_id and viceversa
    Integer route_load_index;  // The index order in load route
    Integer route_unload_index;  // The index order in unload route
}

class OrdersComparable implements Comparator<OrderDocument> {
@Override
public int compare(OrderDocument x, OrderDocument y) {
    if (x.route_load_id == y.route_load_id && x.route_load_id != null)
        return Integer.compare(x.route_load_index, y.route_load_index);

    if (x.route_load_id == y.route_unload_id && x.route_load_id != null)
        return Integer.compare(x.route_load_index, y.route_unload_index);

    if (x.route_unload_id == y.route_load_id && x.route_unload_id != null)
        return Integer.compare(x.route_unload_index, y.route_load_index);

    if (x.route_unload_id == y.route_unload_id && x.route_unload_id != null)
        return Integer.compare(x.route_unload_index, y.route_unload_index);

    return 0;
}
}

Upvotes: 1

Related Questions