As you know, if you would like to sort array, you should use Arrays.sort method.
But if you would like to get sorted index, you should use your a brain a bit.
In this post, I will show you the code snippet for getting sorted array index.
The following is the simplest way to get sorted index.
The disadvantages of the following code are autoboxing in compare process and returned array type is not int[] but Integer[].
/** * The most common & general way. But this method use autoboxing and need Integer[] not int[]. */ public static final <T>void sort(T[] array, Comparator<T> comparator, Integer[] sorted) { Arrays.sort(sorted, (i1, i2) -> comparator.compare(array[i1], array[i2])); }
To solve these advantage, I wrote following array sort helper class which can get sorted array index as int[] type.
You can call getSortedIndex method with source array and comparator as the arguments.
The code uses lambda expression which was introduced in Java 8.
package com.dukesoftware.utils.common; import java.util.Arrays; import java.util.Comparator; import java.util.function.IntFunction; public class ArraySortHelper2 { // Demonstrate how to use getSortedIndex method public static void main(String[] args) { // prepare source array Double[] src = new Double[]{ 1.0, 0.4, 0.3, 0.2, 0.5, 0.9}; // sort ascending int[] sorted = getSortedIndex(src, Double::compare); // expect 3, 2, 1, 4, 5, 0 System.out.println(Arrays.toString(sorted)); } public static final <T>int[] getSortedIndex(T[] array, Comparator<T> comparator) { // sort Holder<T>[] sortedResult = sort(array, comparator); // prepare int[] for storing sorted index int[] sorted = new int[array.length]; // extract only index part from Holder array copyIndex(sortedResult, sorted); return sorted; } // basic sort method public static final <T>Holder<T>[] sort(T[] array, Comparator<T> comparator) { return sort(i -> new Holder<T>(array[i], i), comparator::compare, array.length); } // for primitive type value example // only a disadvantage is that autoboxing is applied when comparing values public static final Holder<Double>[] sort(double[] array) { return sort(i -> new Holder<Double>(array[i], i), Double::compare, array.length); } // generic helper method public static <T>Holder<T>[] sort(IntFunction<Holder<T>> factory, Comparator<T> comparator, int len) { @SuppressWarnings("unchecked") Holder<T>[] copied = fill(new Holder[len], factory); Arrays.sort(copied, (o1, o2) -> comparator.compare(o1.value, o2.value)); return copied; } public static void copyIndex(Holder<?>[] src, int[] dest) { for(int i = 0; i < src.length; i++) { dest[i] = src[i].index; } } private final static <T>T[] fill(T[] array, IntFunction<T> factory) { for(int i = 0; i < array.length; i++) { array[i] = factory.apply(i); } return array; } public final static class Holder<T> { public final int index; public final T value; private Holder(T elem, int index) { this.index = index; this.value = elem; } } }
コメント