Adding Objecting in Priority Queue With multiple comparison

49 Views Asked by At

I have a Priority Queue that containst an Object called it 'RouteInfo',

public class RouteInfo{
    private double totalCost;
    private double totalLeadTime;
    private int numberOfLanes;
    private double totalDistance;
}

I need to add this object inside priority queue based on the value totalCost. But some times this value could be same between two objects, that time i need to compare numberOfLanes value, if this also same then I will go for totalDistance. I have defined a RouteComparator class for this but seems not working.

private class RouteComparator implements Comparator<RouteInfo>{
        
        @Override
        public int compare(RouteInfo routeInfoOne, RouteInfo routeInfoTwo) {
            if(Objects.equals(routeInfoOne.getTotalCost(),routeInfoTwo.getTotalCost())){
                if(routeInfoOne.getNumberOfLanes()==routeInfoTwo.getNumberOfLanes()){
                    if(Objects.equals(routeInfoOne.getTotalLeadTime(),routeInfoTwo.getTotalLeadTime())){
                        if(routeInfoOne.getTotalDistance()<routeInfoTwo.getTotalDistance()){
                            return 1;
                        } else if (routeInfoOne.getTotalDistance()>routeInfoTwo.getTotalDistance()) {
                            return -1;
                        }else{
                            return 0;
                        }
                    }else if(routeInfoOne.getTotalLeadTime()<routeInfoTwo.getTotalLeadTime()){
                        return 1;
                    }else if(routeInfoOne.getTotalLeadTime()>routeInfoTwo.getTotalLeadTime()){
                        return -1;
                    }
                }else if(routeInfoOne.getNumberOfLanes()<routeInfoTwo.getNumberOfLanes()){
                    return 1;
                }else if(routeInfoOne.getNumberOfLanes()>routeInfoTwo.getNumberOfLanes()){
                    return -1;
                }
            }else if (routeInfoOne.getTotalCost() < routeInfoTwo.getTotalCost()) {
                return 1;
            }else if (routeInfoOne.getTotalCost() > routeInfoTwo.getTotalCost())
                return -1;
            return 0;
        }
        
    }

Is this correct, Do i need to do something else for this?

1

There are 1 best solutions below

0
Chaosfire On

The current cognitive complexity of your implementation is overwhelming, it's no wonder it's not working. Simplfy it by using the provided factory methods:

  1. Comparator.comparingDouble()

Accepts a function that extracts a double sort key from a type T, and returns a Comparator that compares by that sort key.

  1. Comparator.thenComparingInt()

Returns a lexicographic-order comparator with a function that extracts a int sort key.

  1. Comparator.thenComparingDouble()

Returns a lexicographic-order comparator with a function that extracts a double sort key.

Then the whole comparator becomes this:

Comparator<RouteInfo> comparator = Comparator.comparingDouble(RouteInfo::getTotalCost)
            .thenComparingInt(RouteInfo::getNumberOfLanes)
            .thenComparingDouble(RouteInfo::getTotalDistance);

You don't specify the required ordering by each key, so you may need to tweak it a bit by reversing the subsequent comparisons (if needed).