如何使用自定义比较器对整数的整数进行sorting?
我需要使用自定义比较器来对整数进行sorting,但是Java的库不提供对比较器整数的sortingfunction(比较器只能与对象一起使用)。 有没有简单的方法来做到这一点?
如果你不能改变你的input数组的types,那么下面的代码将会工作:
final int[] data = new int[] { 5, 4, 2, 1, 3 }; final Integer[] sorted = ArrayUtils.toObject(data); Arrays.sort(sorted, new Comparator<Integer>() { public int compare(Integer o1, Integer o2) { // Intentional: Reverse order for this demo return o2.compareTo(o1); } }); System.arraycopy(ArrayUtils.toPrimitive(sorted), 0, data, 0, sorted.length);
这使用来自commons-lang项目的ArrayUtils
来轻松地在int[]
和Integer[]
之间进行转换,创build数组的副本,进行sorting,然后将sorting后的数据复制到原始数据上。
如何使用stream(Java 8)?
int[] ia = {99, 11, 7, 21, 4, 2}; ia = Arrays.stream(ia). boxed(). sorted((a, b) -> b.compareTo(a)). // sort descending mapToInt(i -> i). toArray();
或就地:
int[] ia = {99, 11, 7, 21, 4, 2}; System.arraycopy( Arrays.stream(ia). boxed(). sorted((a, b) -> b.compareTo(a)). // sort descending mapToInt(i -> i). toArray(), 0, ia, 0, ia.length );
通过转换你的int数组到一个整数,然后使用public static <T> void Arrays.sort(T[] a, Comparator<? super T> c)
(第一步只需要,因为我担心自动装箱可能会工作arrays)。
如果你不想复制数组(假设它非常大),你可能想要创build一个可以用于sorting的包装器List:
final int[] elements = {1, 2, 3, 4}; List<Integer> wrapper = new AbstractList<Integer>() { @Override public Integer get(int index) { return elements[index]; } @Override public int size() { return elements.length; } @Override public Integer set(int index, Integer element) { int v = elements[index]; elements[index] = element; return v; } };
现在,您可以使用自定义比较器对此包装器列表进行sorting。
这是一个辅助方法来完成这项工作。
首先你需要一个新的Comparator接口, 比较器不支持原语:
public interface IntComparator{ public int compare(int a, int b); }
(你当然可以用自动装箱/拆箱来做,但我不会去那里,那很难看)
然后,这里有一个帮助器方法来使用这个比较器对int数组进行sorting:
public static void sort(final int[] data, final IntComparator comparator){ for(int i = 0; i < data.length + 0; i++){ for(int j = i; j > 0 && comparator.compare(data[j - 1], data[j]) > 0; j--){ final int b = j - 1; final int t = data[j]; data[j] = data[b]; data[b] = t; } } }
这里是一些客户端代码。 一个愚蠢的比较器,将所有只包含数字“9”的数字sorting(再次按大小sorting),然后剩下的(无论什么好处):
final int[] data = { 4343, 544, 433, 99, 44934343, 9999, 32, 999, 9, 292, 65 }; sort(data, new IntComparator(){ @Override public int compare(final int a, final int b){ final boolean onlyNinesA = this.onlyNines(a); final boolean onlyNinesB = this.onlyNines(b); if(onlyNinesA && !onlyNinesB){ return -1; } if(onlyNinesB && !onlyNinesA){ return 1; } return Integer.valueOf(a).compareTo(Integer.valueOf(b)); } private boolean onlyNines(final int candidate){ final String str = String.valueOf(candidate); boolean nines = true; for(int i = 0; i < str.length(); i++){ if(!(str.charAt(i) == '9')){ nines = false; break; } } return nines; } }); System.out.println(Arrays.toString(data));
输出:
[9, 99, 999, 9999, 32, 65, 292, 433, 544, 4343, 44934343]
sorting代码来自Arrays.sort(int []) ,我只使用针对微型数组进行优化的版本。 对于一个真正的实现,你可能想看看Arrays类中的内部方法sort1(int[], offset, length)
的源代码。
我最大限度地使用比较原始types本身。 最后,我得出结论,没有办法欺骗比较。这是我的实现。
public class ArrSortComptr { public static void main(String[] args) { int[] array = { 3, 2, 1, 5, 8, 6 }; int[] sortedArr=SortPrimitiveInt(new intComp(),array); System.out.println("InPut "+ Arrays.toString(array)); System.out.println("OutPut "+ Arrays.toString(sortedArr)); } static int[] SortPrimitiveInt(Comparator<Integer> com,int ... arr) { Integer[] objInt=intToObject(arr); Arrays.sort(objInt,com); return intObjToPrimitive(objInt); } static Integer[] intToObject(int ... arr) { Integer[] a=new Integer[arr.length]; int cnt=0; for(int val:arr) a[cnt++]=new Integer(val); return a; } static int[] intObjToPrimitive(Integer ... arr) { int[] a=new int[arr.length]; int cnt=0; for(Integer val:arr) if(val!=null) a[cnt++]=val.intValue(); return a; } } class intComp implements Comparator<Integer> { @Override //your comparator implementation. public int compare(Integer o1, Integer o2) { // TODO Auto-generated method stub return o1.compareTo(o2); } }
@罗曼:我不能说这是一个很好的例子,但是既然你问了这个问题,我就想到了。 假设在一个数组中,你想根据它们的绝对值对数字进行sorting。
Integer d1=Math.abs(o1); Integer d2=Math.abs(o2); return d1.compareTo(d2);
另一个例子可以像你想sorting只有大于100的数字。它实际上取决于情况。我想不出更多的情况。也许Alexandru可以给更多的例子,因为他说他想要使用比较器的int数组。
您可以使用fastutil库中的IntArrays.quickSort(array, comparator)
。