提问人:Diavel 提问时间:9/10/2023 最后编辑:Diavel 更新时间:9/11/2023 访问量:141
如何对 Number 类型的 ArrayList 进行排序
How to sort an ArrayList of type Number
问:
/* Here is a method to sort an array list
* if the array list type is Integer ect this runs just fine
* But errors on Number
*/
public static void sort(ArrayList<Number> list){
Collections.sort(list);
for(Number N: list)
System.out.printf("[%d]",N);
System.out.println();
}
该代码适用于除 Number
以外的任何类型的数组列表。但是我需要使用.Number
答:
-1赞
Reilas
9/10/2023
#1
"...该代码适用于除
Number
以外的任何类型的数组列表。但我被要求使用数字
。
使用 BigDecimal 类进行比较。
list.sort(Comparator.comparing(e -> new BigDecimal(String.valueOf(e))));
public static void sort(ArrayList<Number> list){
list.sort(Comparator.comparing(e -> new BigDecimal(String.valueOf(e))));
for(Number N: list)
System.out.printf("[%s]",N);
System.out.println();
}
此外,还需要将 printf 说明符调整为 ,否则将收到 IllegalFormatConversionException。%s
下面是一个包含一些随机 Number 对象的示例。
ArrayList<Number> list = new ArrayList<>();
list.add(4);
list.add(3f);
list.add(2l);
list.add(1d);
System.out.println(list);
sort(list);
输出
[4, 3.0, 2, 1.0]
[1.0][2][3.0][4]
评论
0赞
M. Justin
9/11/2023
这是假设每个对象的字符串值是 a 的有效表示,并且可以使用 .对于所有内置数字类型来说,这可能是正确的,严格来说,它不能保证对于自定义类型是正确的。Number
BigDecimal
new BigDecimal(value)
Number
0赞
M. Justin
9/12/2023
实际上,即使使用内置类型,也存在无法使用构造函数转换为的值。例如,、 和 。将这些值中的任何一个与此比较器一起使用都将导致被抛出。Number
BigDecimal
BigDecimal(String)
Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY
Double.NaN
NumberFormatException
0赞
Reilas
9/13/2023
@M.贾斯汀,你应该写一个答案。
1赞
Diavel
9/10/2023
#2
为了感谢 Jim Garrison,Number 不是 Comparable
的,因此需要为 Number
数据类型定义 Comparator
。这可以这样完成。
static Comparator<Number> NumberComparator = new Comparator<Number>(){
public int compare(Number n1, Number n2) {
BigDecimal N1,N2;
N1 = new BigDecimal(String.valueOf(n1));
N2 = new BigDecimal(String.valueOf(n2));
return N1.compareTo(N2);
}
};
感谢大家让我走上正确的道路,并在此过程中教我一些技巧。
评论
2赞
Basil Bourque
9/10/2023
您需要使用而不是 .第一个是 64 位,第二个是 32 位,因此任何现有的 or 数字都不适合 .double
float
double
Double
float
1赞
g00se
9/10/2023
else if(n1.floatValue()==n2.floatValue())这里有几件事。如果你想“假设浮点”,最好像我一样做,并假设它具有更高的精度。其次,您应该避免检查浮点值是否绝对相等,因为精度问题可能会产生意想不到的结果,无论如何,f.p.值已经有s了。我的注释代码可以执行您现在正在做的事情,但没有问题double
Comparator
4赞
Basil Bourque
9/10/2023
请注意,这种方法无法正确处理对象(两者都是)。这些对象可能包含超过 64 位容量的数字。BigDecimal
BigInteger
Number
double
1赞
g00se
9/10/2023
@BasilBourque当然是正确的,所以你可以用类似的方式使用BigDecimal
4赞
Bohemian
9/10/2023
不要重新发明轮子:或者只是return Double.compare(n1.doubleValue(), n2.doubleValue());
return Comparator.comparing(Number::doubleValue);
0赞
Oleg Cherednik
9/10/2023
#3
您所需要的只是正确比较值。为此,您应该使用 .double
Double.compare()
但是可以更大,例如,所以一般来说,最好将每个数字转换为并进行比较。Number
BigDecimal
BigDecimal
请记住,这不是有效的解决方案。
public static void sort(List<Number> list) {
list.sort(Comparator.comparing(one -> new BigDecimal(one.toString())));
for (Number N : list)
System.out.printf("[%s]", N);
System.out.println();
}
评论
sort(List,Comparator)
List#sort(Comparator)
Comparator<Number>
Number
Number
不实现,您必须编写一个可以确定实际子类型并调用相应比较器的比较器。Comparable
list.stream().mapToDouble(Number::doubleValue).sorted().forEach(System.out::println);
Number
的所有子类型中的所有可能值,同时保持精度。如果数组包含混合的子类型,事情就会变得更加复杂。我不认为下面的任何答案都解决了这个问题。Number
Number