我有一大堆原始类型(双).如何按降序对元素进行排序?
遗憾的是,Java API不支持使用Comparator对基元类型进行排序.
一种解决方法是排序然后反转:
double[] array = new double[1048576];
Arrays.stream(array).boxed().sorted(Collections.reverseOrder())…
Run Code Online (Sandbox Code Playgroud)
这很慢 - 特别是如果阵列已经排序得很好.
什么是更好的选择?
Rea*_*ted 18
Java Primitive包括基于自定义比较器对原始数组进行排序的功能.使用它和Java 8,您的示例可以写成:
double[] array = new double[1048576];
...
Primitive.sort(array, (d1, d2) -> Double.compare(d2, d1), false);
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Maven,则可以将其包含在:
<dependency>
<groupId>net.mintern</groupId>
<artifactId>primitive</artifactId>
<version>1.2.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
当您false作为第三个参数传递时sort,它使用不稳定的排序,简单编辑Java的内置双枢轴快速排序.这意味着速度应该接近内置排序的速度.
完全披露:我写了Java Primitive库.
小智 16
我认为最好不要重新发明轮子并使用Arrays.sort().
是的,我看到了"下降"部分.排序是困难的部分,您希望从Java库代码的简单性和速度中受益.一旦完成,你只需反转数组,这是一个相对便宜的O(n)操作.以下是我发现的一些代码,只需4行:
for (int left=0, right=b.length-1; left<right; left++, right--) {
// exchange the first and last
int temp = b[left]; b[left] = b[right]; b[right] = temp;
}
Run Code Online (Sandbox Code Playgroud)
Guava具有将原始数组转换为包装类型列表的方法.好的部分是这些列表是实时视图,因此对它们的操作也适用于底层数组(类似于Arrays.asList()但是对于基元).
无论如何,这些列表中的每一个都可以传递给Collections.reverse():
int[] intArr = { 1, 2, 3, 4, 5 };
float[] floatArr = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
double[] doubleArr = { 1.0d, 2.0d, 3.0d, 4.0d, 5.0d };
byte[] byteArr = { 1, 2, 3, 4, 5 };
short[] shortArr = { 1, 2, 3, 4, 5 };
Collections.reverse(Ints.asList(intArr));
Collections.reverse(Floats.asList(floatArr));
Collections.reverse(Doubles.asList(doubleArr));
Collections.reverse(Bytes.asList(byteArr));
Collections.reverse(Shorts.asList(shortArr));
System.out.println(Arrays.toString(intArr));
System.out.println(Arrays.toString(floatArr));
System.out.println(Arrays.toString(doubleArr));
System.out.println(Arrays.toString(byteArr));
System.out.println(Arrays.toString(shortArr));
Run Code Online (Sandbox Code Playgroud)
输出:
并[5,4,3,2,1]
[5.0,4.0,3.0,2.0,1.0]
[5.0,4.0,3.0,2.0,1.0]
[5,4,3,2,1]
[5,4,3 ,2,1]
小智 8
这是一个单行代码,使用 Java 8 中的流
int arr = new int[]{1,2,3,4,5};
Arrays.stream(arr).boxed().sorted(Collections.reverseOrder()).mapToInt(Integer::intValue).toArray();
Run Code Online (Sandbox Code Playgroud)