
Java’s ArrayList cannot be sorted directly with Collections.sort() because Number itself doesn’t implement Comparable; a custom Comparator—using BigDecimal for precise numeric comparison—is required.
java’s `arraylist
When working with generic collections in Java, type safety and interface contracts matter. Although Integer, Double, Long, and other numeric wrapper types individually implement Comparable, their common supertype Number does not—it’s an abstract class with no natural ordering. As a result, calling Collections.sort(list) on an ArrayList<number></number> fails at compile time with:
error: no suitable method found for sort(ArrayList<Number>)
To resolve this, you must supply an explicit Comparator<number></number>. The safest approach is to convert each Number to BigDecimal, which preserves exact decimal precision (unlike double-based comparisons that risk rounding errors or NaN/Infinity edge cases). Here's a robust, reusable solution:
import java.math.BigDecimal;
import java.util.*;
public class NumberSorter {
public static final Comparator<Number> NUMBER_COMPARATOR = (n1, n2) -> {
BigDecimal bd1 = new BigDecimal(String.valueOf(n1));
BigDecimal bd2 = new BigDecimal(String.valueOf(n2));
return bd1.compareTo(bd2);
};
public static void sort(ArrayList<Number> list) {
Collections.sort(list, NUMBER_COMPARATOR);
list.forEach(n -> System.out.printf("[%s]", n));
System.out.println();
}
// Example usage
public static void main(String[] args) {
ArrayList<Number> numbers = new ArrayList<>();
numbers.add(42); // Integer
numbers.add(3.14159); // Double
numbers.add(new BigDecimal("2.71828")); // BigDecimal
numbers.add(100L); // Long
numbers.add(-7.5f); // Float
sort(numbers); // Output: [-7.5, 2.71828, 3.14159, 42, 100]
}
}✅ Why BigDecimal(String.valueOf(...))?
-
String.valueOf(n)handles allNumbersubclasses uniformly (no lossy casting liken.doubleValue()). - Avoids
Double.NaN,Double.POSITIVE_INFINITY, or precision loss from floating-point conversion. - Ensures consistent lexicographic-to-numeric parsing (e.g.,
"0.1"→ exact0.1, not0.10000000000000000555...).
⚠️ Important notes:
立即学习“Java免费学习笔记(深入)”;
- Never use
n.doubleValue()orn.longValue()in the comparator—this breaks ordering for largeBigInteger,BigDecimal, or imprecise floats. - The comparator must be consistent with equals: if
compare(a,b) == 0, thena.equals(b)should ideally hold—but sinceNumbersubclasses overrideequals()inconsistently (e.g.,new Integer(5).equals(new Long(5))isfalse), treat sorting as value-based, not identity-based. - For performance-critical code with homogeneous input (e.g., only
IntegerandLong), consider type-checking and optimized paths—butBigDecimalremains the most universally correct default.
In summary: sorting ArrayList<number></number> requires an explicit, value-accurate Comparator, and BigDecimal-based comparison delivers correctness, clarity, and cross-type reliability.


















