【问题标题】:Help comparing float member variables using Comparators帮助使用 Comparator 比较浮点成员变量
【发布时间】:2011-04-11 22:35:10
【问题描述】:

我可以很好地比较字符串,但想知道如何对浮点数进行排名?

getChange() 返回一个字符串。我希望能够降序排序。我该怎么做?

更新:

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

我收到编译时错误:

This method must return a result of type int    ChangeComparator.java   

【问题讨论】:

  • 除了 NaN 问题,您的代码中没有保证返回语句。实际上你是这样做的,但编译器无法判断,因为你有三个不同的 if 语句。它直到运行时才能评估这些,所以它认为你实际上可以通过最后一个 if 语句并且没有 return 子句。

标签: java sorting arraylist comparator comparable


【解决方案1】:

阅读Comparator#compare()方法的javadoc。

比较它的两个参数的顺序。 返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数。

所以,基本上

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

或者如果你喜欢条件运算符:

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

但是,您需要考虑Float.NaN。我不确定您希望如何订购它们。第一的?最后的?一样吗?

【讨论】:

  • 当心 Float.NaN!我假设您的数据没有 NaN,但由于任何比较的一侧的 NaN 将始终返回 false(即使 Float.NaN==Float.NaN 为 false!),您可能需要 Float.isNaN(change1)或任何检查。否则,如果涉及 NaN,则排序显然是随机的。
  • 我收到编译时错误(请参阅我的问题中的更新代码):此方法必须返回 int ChangeComparator.java 类型的结果
  • 编译错误不言自明。您需要确保它总是返回int。我将编辑示例。
【解决方案2】:

这个怎么样:

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

请注意,Java 1.4 引入了Float#compare(float, float)(以及Double 中的等价物),几乎可以直接使用:

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

(编辑后,我注意到@BorislavGizdov 已经在他的回答中提到了这一点。)


另外值得注意的是,Java 8 Comparator#comparing(...)Comparator#comparingDouble(...) 提供了一种直接构建这些比较器的简单方法。

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

将使用加框的Float 值进行比较。

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

将使用提升为double 值的float 值进行比较。

鉴于没有Comparator#comparingFloat(...),我更喜欢使用comparingDouble(...) 方法,因为这仅涉及原始类型转换,而不是装箱。

【讨论】:

  • 这是最好的答案 - 将比较委托给 Float 的 compareTo。
【解决方案3】:

你可以使用Float.compare(float f1, float f2):

  public static int compare(float f1, float f2)

比较两个指定的浮点值。如果 f1 在数值上等于 f2,则返回值 0;如果 f1 在数值上小于 f2,则值小于 0;如果 f1 在数值上大于 f2,则值大于 0。

【讨论】:

    【解决方案4】:
    import java.io.*;
    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            Scanner input = new Scanner(System.in);
            int tc = input.nextInt();
            int alpha = 0;
            while (tc-- > 0) {
                int ttc = input.nextInt();
                int sort = input.nextInt();
                input.nextLine();
                Vector<student> v = new Vector<>();
                alpha++;
                while (ttc-- > 0) {
                    String name = input.next();
                    int weit = input.nextInt();
                    int age = input.nextInt();
                    float hight = input.nextFloat();
    
                    v.add(new student(name, weit, age, hight));
                }
                Collections.sort(v);
                int count = 0;
                System.out.println("CENARIO {" + alpha + "}");
                for (student s : v) {
                    System.out.print((count + 1) + " - ");
                    System.out.println(s.name);
                    count++;
                    if (count == sort) {
                        break;
                    }
                }
            }
        }
    
        private static class student implements Comparable<student> {
    
            String name;
            int weit;
            int age;
            float hight;
    
            public student(String name, int weit, int age, float hight) {
                this.name = name;
                this.weit = weit;
                this.age = age;
                this.hight = hight;
            }
    
            @Override
            public int compareTo(student t) {
                if (this.weit - t.weit != 0) {
                    return t.weit - this.weit;
                }
                if (this.age - t.age != 0) {
                    return this.age - t.age;
                }
                if (this.hight - t.hight != 0) {
                    return Float.compare(this.hight, t.hight);
                }
                return this.name.compareTo(t.name);
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-26
      • 2010-09-29
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多