Java 为什么SortBy值的结果是错误的?
我正在尝试使用Java 为什么SortBy值的结果是错误的?,java,collections,Java,Collections,我正在尝试使用compareTo方法按提供值对列表进行排序。 如果offerValue是一个像8.00这样的一位数,那么它工作得很好,但是如果offerValue是20.00或15.00,它将它们视为2(对于20.00)和1(对于15.00)。我不明白 Comparator<OfferVO> comparatorAsc = (o1, o2) -> { if (o1.getOfferValue() == null && o2.getOfferValue()
compareTo
方法按提供值对列表进行排序。
如果offerValue是一个像8.00这样的一位数,那么它工作得很好,但是如果offerValue是20.00或15.00,它将它们视为2(对于20.00)和1(对于15.00)。我不明白
Comparator<OfferVO> comparatorAsc = (o1, o2) -> {
if (o1.getOfferValue() == null && o2.getOfferValue() == null) {
return 0;
} else if (o1.getOfferValue() != null) {
return o1.getOfferValue().compareTo(o2.getOfferValue());
} else {
return -1;
}
};
Collections.sort(offersList, comparatorAsc);
输出样本:
public class OfferVO extends OfferBaseVO implements Serializable {
private static final long serialVersionUID = 1L;
private String offerValue;
public String getOfferValue() {
return offerValue;
}
public void setOfferValue(String offerValue) {
this.offerValue = offerValue;
}
}
"offerValue": "5.00",
"offerValue": "3.00",
"offerValue": "3.00",
"offerValue": "20.00",
"offerValue": "15.00",
"offerValue": "15.00",
字符串是(通俗地说是字母顺序),而不是数字。这意味着“10”
将位于“2”
之前,依此类推。如果要比较数值,需要将字符串解析为数字,例如。字符串是(按字母顺序),而不是数字。这意味着“10”
将位于“2”
之前,依此类推。如果要比较数值,则需要将字符串解析为数字,例如。1)要将字符串作为数值进行比较,请在比较器中将其转换为数字作为字符串。compare()
依赖于字典顺序
2) 请注意,比较器不是对称的
Comparator.compare()
规范规定:
实现者必须确保sgn(compare(x,y))==-sgn(compare(y,
x) )适用于所有x和y
在这里:
else if (o1.getOfferValue() != null) {
return o1.getOfferValue().compareTo(o2.getOfferValue());
}
仅依靠o1.getOfferValue()的非空性来比较这两个对象:
要编写关于舍入的更精确的数值比较,您应该在比较浮动值时使用ε,例如
float epsilon = 0.0001F;
if (o1.getOfferValue() == null && o2.getOfferValue() == null){
return 0;
} else if (o1.getOfferValue() != null && o2.getOfferValue() != null) {
return Math.abs(Float.valueOf(o1.getOfferValue()) - Float.valueOf(o2.getOfferValue())) < epsilon)
}
// TODO
// as last you have to decide here how to sort if only one of the value is not null
1) 若要将字符串作为数值进行比较,请在比较器中将它们转换为数字作为String。compare()
依赖于字典顺序
2) 请注意,比较器不是对称的
Comparator.compare()
规范规定:
实现者必须确保sgn(compare(x,y))==-sgn(compare(y,
x) )适用于所有x和y
在这里:
else if (o1.getOfferValue() != null) {
return o1.getOfferValue().compareTo(o2.getOfferValue());
}
仅依靠o1.getOfferValue()的非空性来比较这两个对象:
要编写关于舍入的更精确的数值比较,您应该在比较浮动值时使用ε,例如
float epsilon = 0.0001F;
if (o1.getOfferValue() == null && o2.getOfferValue() == null){
return 0;
} else if (o1.getOfferValue() != null && o2.getOfferValue() != null) {
return Math.abs(Float.valueOf(o1.getOfferValue()) - Float.valueOf(o2.getOfferValue())) < epsilon)
}
// TODO
// as last you have to decide here how to sort if only one of the value is not null
使用以下代码:
Comparator<OfferVO> comparatorDesc = (o1, o2) -> {
if (o1.getOfferValue() == null && o2.getOfferValue() == null) {
return 0;
} else if (o2.getOfferValue() != null) {
return
Double.valueOf(o2.getOfferValue()).compareTo(Double.valueOf(o1.getOfferValue()));
} else {
return -1;
}
};
比较器比较器Desc=(o1,o2)->{
if(o1.getOfferValue()==null&&o2.getOfferValue()==null){
返回0;
}else if(o2.getOfferValue()!=null){
返回
Double.valueOf(o2.getOfferValue()).compareTo(Double.valueOf(o1.getOfferValue());
}否则{
返回-1;
}
};
使用以下代码:
Comparator<OfferVO> comparatorDesc = (o1, o2) -> {
if (o1.getOfferValue() == null && o2.getOfferValue() == null) {
return 0;
} else if (o2.getOfferValue() != null) {
return
Double.valueOf(o2.getOfferValue()).compareTo(Double.valueOf(o1.getOfferValue()));
} else {
return -1;
}
};
比较器比较器Desc=(o1,o2)->{
if(o1.getOfferValue()==null&&o2.getOfferValue()==null){
返回0;
}else if(o2.getOfferValue()!=null){
返回
Double.valueOf(o2.getOfferValue()).compareTo(Double.valueOf(o1.getOfferValue());
}否则{
返回-1;
}
};
猜测一下,getOfferValue
返回的是一个字符串
,但是没有更多的上下文,这只是猜测而已。我们需要查看OfferVO的代码
您可以共享OfferVO代码和您添加的OfferVO类的输出吗?您想用数字进行比较,但可以使用字符串存储您的数字。字符串按字典顺序排序。使用适当的类型(数字:double或BigDecimal)存储数值。据猜测,getOfferValue
正在返回一个字符串,但没有更多上下文,这只是一个猜测,我们需要查看OfferVO的代码。您是否可以共享OfferVO代码和您获得的输出?您添加了OfferVO类,您希望进行数字比较,但您使用字符串存储您的数字。字符串按字典顺序排序。使用适当的类型(数字:double或BigDecimal)存储数值。Math.abs(Float.valueOf(o1.getOfferValue())-Float.valueOf(o2.getOfferValue())
非常难看。为什么不使用
Float。而使用进行比较?@ortis它不是强制性的。它是为了防止舍入误差。我更新了。您可以使用新的BigDecimal(o.getOfferValue())
(JB Nizet在对问题的评论中提到)来防止舍入错误。这将提供数字的全部精度。@davidxx不应该是Float.valueOf(o1.getOfferValue()).compareTo(Float.valueOf(o2.getOfferValue));事实上我把两者都混在一起了<代码>浮动。compareTo(浮动)将需要一个不必要的装箱浮动。由于前面选中了null,Float.compare(Float,Float)
很好。Math.abs(Float.valueOf(o1.getOfferValue())-Float.valueOf(o2.getOfferValue())
非常难看。为什么不使用Float。而使用进行比较?@ortis它不是强制性的。它是为了防止舍入误差。我更新了。您可以使用新的BigDecimal(o.getOfferValue())
(JB Nizet在对问题的评论中提到)来防止舍入错误。这将提供数字的全部精度。@davidxx不应该是Float.valueOf(o1.getOfferValue()).compareTo(Float.valueOf(o2.getOfferValue));事实上我把两者都混在一起了<代码>浮动。compareTo(浮动)将需要一个不必要的装箱浮动。由于前面选中了null,Float.compare(Float,Float)
可以。