Comparator接口用于比较双精度数。

huangapple go评论103阅读模式
英文:

Comparator interface used to compare doubles

问题

I'm using Comparator Interface to compare custom objects to sort ArrayList's. This works fine with int and String values, but when I want to sort/compare doubles I run into troubles.

I know that Java rounds the double in my method and reads 1.7, 1.62, 1.66 as 1, which is the error.

But I can't seem to find a way to overcome this. Here are my methods and result - the result shows that the Comparator does not sort the list correctly due to the conversion of double to int.

Note that my "odds" variable is a double value and has to be converted to a function in the Comparator Interface:

public Integer getOddsInt() {
    return (int) odds;
}

public class SortOdds implements Comparator<History>{

     public int compare(History a, History b) 
    { 
        return a.getOddsInt() - b.getOddsInt(); 
    }
}

Result:

[ 
  2.62 |  
, 1.7  |  
, 1.62 | 
, 1.66 | 
]
英文:

I'm using Comparator Interface to compare custom objects to sort ArrayList's. This works fine with int and String values, but when I want to sort/compare doubles I run into troubles.

I know that Java rounds the double in my method and reads 1.7, 1.62, 1.66 as 1, which is the error.

But I cant seem to find a way to overcome this. Here are my methods and result - the result show that the Comparator does not sort the list correctly due to the convertion of double to int.

Note that my "odds" variable is value double and have to be converted to function in Comparator Interface:

public Integer getOddsInt() {
		return (int) odds;
	}


public class SortOdds implements Comparator &lt;History&gt;{
	
	 public int compare(History a, History b) 
	    
	 	{ 
	        return a.getOddsInt() - b.getOddsInt(); 
	    }
}

Result:

[ 
  2.62 |  
, 1.7  |  
, 1.62 | 
, 1.66 | 
]

答案1

得分: 2

以下是您要翻译的内容:

"You appear to be a bit confused - if you want to sort 1.4 before 1.6, but your only possible view of this data is as just '1', what you want is obviously impossible.

But you're the boss of your own code. As the doctor said when the woman asked: 'Doctor, it hurts when I wallop myself in the face with a hammer': 'Well, stop doing that then!'.

Make a method that returns the odds as an actual double. Alternatively, if the SortOdds class is inside the History class, you can directly access the field, which I assume looks something like private final double odds;.

compare demands you return an int, but your approach of - is a common trope that is wrong. Don't write your compare runs that way, they don't work for extreme values.

You can't really get away from:

if (a.getOdds() < b.getOdds()) return -1;
if (a.getOdds() > b.getOdds()) return +1;
return 0;

but fortunately, the method Double.compare(a, b) does precisely that. So...:

return Double.compare(a.odds, b.odds);

is all you need.

NB: You can make this stuff a ton easier these days:

public class History {
    public static final Comparator<History> ODDS_BASED_COMPARATOR =
      Comparator.comparingDouble(History::getOdds);

    private final double odds;

    public double getOdds() { return odds; }
}

// and to use, for example:

List<History> list = new ArrayList<History>();
// add some history objects to it here
list.sort(History.ODDS_BASED_COMPARATOR);

"

英文:

You appear to be a bit confused - if you want to sort 1.4 before 1.6, but your only possible view of this data is as just '1', what you want is obviously impossible.

But you're the boss of your own code. As the doctor said when the woman asked: "Doctor, it hurts when I wallop myself in the face with a hammer": "Well, stop doing that then!".

Make a method that returns the odds as an actual double. Alternatively, if the SortOdds class is inside the History class, you can directly access the field, which I assume looks something like private final double odds;.

compare demands you return an int, but your approach of - is a common trope that is wrong. Don't write your compare runs that way, they don't work for extreme values.

You can't really get away from:

if (a.getOdds() &lt; b.getOdds()) return -1;
if (a.getOdds() &gt; b.getOdds()) return +1;
return 0;

but fortunately, the method Double.compare(a, b) does precisely that. So...:

return Double.compare(a.odds, b.odds);

is all you need.

NB: You can make this stuff a ton easier these days:

public class History {
    public static final Comparator&lt;History&gt; ODDS_BASED_COMPARATOR =
      Comparator.comparingDouble(History::getOdds);

    private final double odds;

    public double getOdds() { return odds; }
}

// and to use, for example:

List&lt;History&gt; list = new ArrayList&lt;History&gt;();
// add some history objects to it here
list.sort(History.ODDS_BASED_COMPARATOR);

答案2

得分: -1

如果这会引起问题,那就完全不进行转换。只需使用if-else逻辑。

if (a.getDouble() < b.getDouble()) {
  return -1;
} else if (a.getDouble() > b.getDouble()) {
  return 1;
} else {
  return 0;
}
英文:

If that is causing trouble, don't do the conversion at all. Just use if-else logic

if (a.getDouble() &lt; b.getDouble) {
  return -1 ;
else if (a.getDouble() &gt; b.getDouble){
  return 1 ;
} else {
  return 0 ;
}

}

huangapple
  • 本文由 发表于 2020年8月12日 19:19:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63375416.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定