gpt4 book ai didi

How to sort an ArrayList of type Number(如何对Numbers类型的ArrayList进行排序)

转载 作者:bug小助手 更新时间:2023-10-27 19:55:14 25 4
gpt4 key购买 nike



/* 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();
}

The code works fine for an array list of any type except Number. But I am required to use Number.

这段代码对于除Number之外的任何类型的数组列表都可以正常工作。但我必须使用号码。


更多回答

Use the sort(List,Comparator) overload (or just List#sort(Comparator)) and supply a Comparator<Number> that appropriately compares the Number objects. How you determine what an "appropriate comparison" is either up to you, inferable from other constraints, or you need to ask for clarification from your professor.

使用sort(List,Comparator)重载(或仅使用List#sort(Comparator))并提供一个Comparator来适当地比较Number对象。你如何确定什么是“适当的比较”,要么取决于你,从其他限制中推断出来,要么你需要向你的教授寻求澄清。

Number does not implement Comparable, you'd have to write a comparator that can determine the actual subtype and call the appropriate comparator.

Number不实现可比较,则必须编写一个比较器来确定实际子类型并调用适当的比较器。

Rough and ready but you might try list.stream().mapToDouble(Number::doubleValue).sorted().forEach(System.out::println);

粗制滥造,但你可以试试list.stream().mapToDouble(Number::doubleValue).sorted().forEach(System.out::println);

This is a subtle and quite difficult problem. You have to consider both the ranges and precisions of all the possible Number representations and handle each representation as a distinct case. There is no one type that encompasses all possible values in all the subtypes of Number while preserving precision. And things get even more complex if the array contains a mixture of Number subtypes. I don't think any of the answers below address this issue.

这是一个微妙而又相当困难的问题。您必须同时考虑所有可能的数字表示的范围和精度,并将每个表示作为不同的情况处理。没有一种类型可以在保持精度的同时包含Numbers的所有子类型中的所有可能值。如果数组包含Numer子类型的混合,事情就会变得更加复杂。我认为下面的任何答案都不会解决这个问题。

优秀答案推荐

To give credit to Jim Garrison, Number is not Comparable so a Comparator needs to be defined for the Number data type. This can be done as such.

为了给Jim Garrison加分,Number是不可比较的,因此需要为Numbers数据类型定义一个比较器。这是可以做到的。


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

}
};

Thank you all for sending me down the right path and teaching me some tricks along the way.

感谢你们把我送上了正确的道路,并教会了我一些诀窍。



All you need is correctly compare double values. To do this, you should use Double.compare().

你所需要的就是正确地比较两个值。要做到这一点,您应该使用Double.Compare()。


But Number can be greater, e.g. BigDecimal, so in general way it is better to convert each number to BigDecimal and compare it then.

但数字可以更大,例如BigDecimal,所以一般来说,最好将每个数字转换为BigDecimal,然后进行比较。


Remember, this is not efficient solution.

请记住,这不是有效的解决方案。


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



"... The code works fine for an array list of any type except Number. But I am required to use Number."



Use the BigDecimal class for comparison.

使用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();
}

Also, you'll need to adjust the printf specifier to %s, or you'll receive an IllegalFormatConversionException.

此外,您还需要将printf说明符调整为%S,否则将收到IlLegalFormatConversionException异常。


Here is an example with some random Number objects.

下面是一个包含一些随机数对象的示例。


ArrayList<Number> list = new ArrayList<>();
list.add(4);
list.add(3f);
list.add(2l);
list.add(1d);
System.out.println(list);
sort(list);

Output

输出


[4, 3.0, 2, 1.0]
[1.0][2][3.0][4]

更多回答

You need to use double rather than float. The first is 64-bit, the second is 32-bit, so any existing double or Double numbers will not fit into a float.

您需要使用Double而不是Float。第一个是64位的,第二个是32位的,所以任何现有的双精度数或双精度数都不适合浮点数。

else if(n1.floatValue()==n2.floatValue()) A couple of things here. If you want to 'assume floating point', it would be better to do it like I did, and assume double as it has greater precision. Secondly, you should avoid checking floating point values for absolute equality as precision issues can produce unexpected results, and anyway there are already Comparators for f.p. values. My comment code does what you're now doing, but without the problems

Else if(n1.flatValue()==n2.flatValue()这里有几件事。如果你想‘假设浮点数’,最好是像我这样做,并假设双精度,因为它有更高的精度。其次,您应该避免检查浮点值的绝对相等,因为精度问题可能会产生意想不到的结果,而且无论如何f.p已经有了比较程序。价值观。我的注释代码做了您现在正在做的事情,但没有问题

Be aware that such an approach fails to handle BigDecimal & BigInteger objects (both are Number) correctly. These objects may contain numbers that exceed the capacity of 64-bit double.

请注意,这种方法无法正确处理BigDecimal和BigInteger对象(两者都是数字)。这些对象可能包含超过64位双精度的容量的数字。

@BasilBourque is of course correct, so you might use BigDecimal in a similar way

@BasilBourque当然是正确的,因此您可以以类似的方式使用BigDecimal

Don't reinvent the wheel: return Double.compare(n1.doubleValue(), n2.doubleValue()); or just return Comparator.comparing(Number::doubleValue);

不要重新发明轮子:返回Double.Compare(n1.doubleValue(),n2.doubleValue());或者只返回比较.比较(number::doubleValue);

This is making the assumption that the string value of each Number object is a valid representation of a BigDecimal and can be converted to such using new BigDecimal(value). Which this may be true for all built-in number types, strictly speaking it's not guaranteed to be true for custom Number types.

这是在假设每个Number对象的字符串值是BigDecimal的有效表示形式,并且可以使用新的BigDecimal(Value)将其转换为这种形式。这可能适用于所有内置数字类型,严格来说,不能保证自定义数字类型也适用。

Actually, even with built-in Number types, there exist values that cannot be converted to BigDecimal using the BigDecimal(String) constructor. For instance, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, and Double.NaN. Using any of these values with this comparator will result in a NumberFormatException being thrown.

实际上,即使使用内置的Number类型,也存在无法使用BigDecliter(String)构造函数转换为BigDecliter的值。例如,Double.Positive_INFINITY、Double.NEGATIVE_INFINITY和Double.NaN。在这个比较器中使用这些值中的任何一个都将导致抛出NumberException。

@M.Justin, you should write an answer.

@M.Justin,你应该写一个答案。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com