Get min and max value of multiple elements using Comparable

I am trying to get records from min distance, min speed and max speed

as a result of my query. I am currently getting the shortest distance, but I am facing a problem to get the min and max speed and I am asking myself if it is possible to add another method public int compareTo(BehaviourItem otherItem)

to the class BehaviourItem

to achieve this, but I am getting an error Duplicate method compareTo(BehaviourItem) in type BehaviourItem

.

How can I get the minimum and maximum speed from the class BehaviourItem

?

Code:

         PreparedStatement prepared = con
                 .prepareStatement("SELECT speed, stop_distance from behaviour where mac = ? and stop_name = ?");
                 prepared.setString(1, macD);
                 prepared.setString(1, sto_nam);
                 ResultSet rsBehav = prepared.executeQuery();
                 List<BehaviourItem> behavList = new ArrayList<BehaviourItem>();
                 while (rsBehav.next()) {
                     int distance = rsBehav.getInt("stop_distance");
                     int speed = rsBehav.getInt("speed");
                     BehaviourItem behItem = new BehaviourItem(distance, speed);
                     behavList.add(behItem);

                 }
                 Collections.sort(behavList);
                 int minDistance =  behavList.get(0).getDistance();

      

BehaviourItem class:

public class BehaviourItem implements Comparable<BehaviourItem>{
    int speed;
    int distance;

    public BehaviourItem(int speed, int distance) {
        super();
        this.speed = speed;
        this.distance = distance;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getDistance() {
        return distance;
    }

    public void setDistance(int distance) {
        this.distance = distance;
    }

    @Override
    public int compareTo(BehaviourItem otherItem) {
        // TODO Auto-generated method stub
        return Integer.compare(this.distance, otherItem.distance);
    }

}

      

+3


source to share


4 answers


Cannot be used BehaviourItem

Comparable

as it has no natural order. Instead, implement different Comparator

s
for different properties.

Note that in Java 8 you can implement something as Comparator

simple as

Comparator<BehaviourItem> orderBySpeed=Comparator.comparingInt(BehaviourItem::getSpeed);

      

which is equivalent

Comparator<BehaviourItem> orderBySpeed=new Comparator<BehaviourItem>() {
    public int compare(BehaviourItem a, BehaviourItem b) {
        return Integer.compare(a.getSpeed(), b.getSpeed());
    }
};

      

or

Comparator<BehaviourItem> orderByDistance
                         =Comparator.comparingInt(BehaviourItem::getDistance);

      

for another property.

Almost every collection method using order has overloading support to pass Comparator

in order to define the order rather than using natural ordering:

Collections.sort(behavList, orderBySpeed);

      



respectively.

Collections.sort(behavList, orderByDistance);

      


You can even create an ad-hoc comparator:

Collections.sort(behavList, Comparator.comparingInt(BehaviourItem::getDistance));

      

and

Collections.sort(behavList, Comparator.comparingInt(BehaviourItem::getSpeed));

      

but the stream API allows you to search for the minimum or maximum value even without sorting:

Optional<BehaviourItem> minBySpeed=behavList.stream()
                       .max(Comparator.comparingInt(BehaviourItem::getSpeed));

      

+7


source


Comparable

basically defines an object that has natural ordering (like numbers) and therefore there can only be one method compareTo()

.

To get the min / max for a single value, you can use a sorted collection for example. list and access to the first and last items.

However, since your BehaviorItem does not have a natural ordering (would it be in speed or distance?), You will need to define an order based on the situation. What comes into play Comparator

: when you want to sort by speed, you use a comparator that compares the speed, if you want to sort by distance, you use a comparator for distance, etc.



Of course, if the speed and distance change a lot and you always need to get the min / max for both, you can also just iterate over all the items and choose the min / max the classic way.

Another option, since you are using query anyway, might be to add directly min(speed), max(speed)

, etc. This will either require a separate query or be added to each row of results, which in turn can slow down the query speed, but if you only get a few rows that might still be worth it.

+1


source


You cannot define another function compareTo()

in your class BehaviourItem

, but you can create your own comparators and use them to sort the list.

An example of a custom comparator -

public class BehaviourItem implements Comparable<BehaviourItem>{
    .
    .
    .

    @Override
    public int compareTo(BehaviourItem otherItem) {
        // TODO Auto-generated method stub
        return Integer.compare(this.distance, otherItem.distance);
    }

    static class BehaviourItemComparator implements Comparator<BehaviourItem>
    {            
         public int compare(BehaviourItem b1, BehaviourItem b2)
         {
             return Integer.compare(b1.getSpeed(), b2.getSpeed());
         }
     }

}

      

Then you can use it like -

Collections.sort(behavList, BehaviourItem.BehaviourItemComparator)

      

+1


source


Use Comparator

instead Comparable

.

You can define as many ordering actions as possible.

0


source







All Articles