Help comparing float member variables using Comparators

21,151

Solution 1

Read the javadoc of Comparator#compare() method.

Compares its two arguments for order. Returns a negative integer, zero or a positive integer as the first argument is less than, equal to or greater than the second.

So, basically:

float change1 = o1.getChange();
float change2 = o2.getChange();
if (change1 < change2) return -1;
if (change1 > change2) return 1;
return 0;

Or if you like conditional operators:

return o1.getChange() < o2.getChange() ? -1 
     : o1.getChange() > o2.getChange() ? 1 
     : 0;

You however need to take account with Float.NaN. I am not sure how you'd like to have them ordered. First? Last? Equally?

Solution 2

How about this:

public class ChangeComparator implements Comparator<Quote>
{
    public int compare(Quote o1, Quote o2) {
        Float change1 = Float.valueOf(o1.getChange());
        Float change2 = Float.valueOf(o2.getChange());
        return change1.compareTo(change2);
    }
}

Note that Java 1.4 introduced Float#compare(float, float) (and an equivalent in Double), which can be pretty much used directly:

public class ChangeComparator implements Comparator<Quote>
{
    public int compare(Quote o1, Quote o2) {
        return Float.compare(o1.getChange(), o2.getChange());
    }
}

(After editing, I notice that @BorislavGizdov has mentioned this in his answer already.)


Also worth noting that Java 8 Comparator#comparing(...) and Comparator#comparingDouble(...) provide a straightforward way of constructing these comparators directly.

Comparator<Quote> changeComparator = Comparator.comparing(Quote::getChange);

Will compare using boxed Float values.

Comparator<Quote> changeComparator = Comparator.comparingDouble(Quote::getChange);

Will compare using float values promoted to double values.

Given that there is no Comparator#comparingFloat(...), my preference would be to use the comparingDouble(...) method, as this only involves primitive type conversion, rather than boxing.

Solution 3

You can use Float.compare(float f1, float f2):

  public static int compare(float f1, float f2)

Compares the two specified float values. Returns the value 0 if f1 is numerically equal to f2; a value less than 0 if f1 is numerically less than f2; and a value greater than 0 if f1 is numerically greater than f2.

Share:
21,151
Sheehan Alam
Author by

Sheehan Alam

iOS, Android and Mac Developer. i can divide by zero.

Updated on July 05, 2022

Comments

  • Sheehan Alam
    Sheehan Alam almost 2 years

    I am able to compare Strings fine, but would like to know how I can rank floating point numbers?

    getChange() returns a String. I want to be able to sort descending. How can I do this?

    UPDATE:

    package org.stocktwits.helper;
    
    import java.util.Comparator;
    
    import org.stocktwits.model.Quote;
    
    public class ChangeComparator implements Comparator<Quote>
    {
        public int compare(Quote o1, Quote o2) {
            float change1 = Float.valueOf(o1.getChange());
            float change2 = Float.valueOf(o2.getChange());
    
            if (change1 < change2) return -1;
            if (change1 == change2) return 0; // Fails on NaN however, not sure what you want
            if (change2 > change2) return 1;
        }
    }
    

    I am getting the compile time error:

    This method must return a result of type int    ChangeComparator.java   
    
  • John Gardner
    John Gardner almost 14 years
    watch out for Float.NaN! I'm presuming your data doesn't have NaNs, but since NaN on one side of any comparison will always return false (even Float.NaN==Float.NaN is false!), you might want a Float.isNaN(change1) or whatever check. otherwise the sort will be apparently random if there are NaN's involved.
  • Sheehan Alam
    Sheehan Alam almost 14 years
    I am getting the compile time error (see updated code in my question): This method must return a result of type int ChangeComparator.java
  • BalusC
    BalusC almost 14 years
    The compilation error speaks for itself. You need to make sure that it always returns an int. I'll edit the example.
  • Steve Kuo
    Steve Kuo almost 14 years
    This is the best answer - delegate the comparison to Float's compareTo.