sorting后获取数组的索引?

假设用户input一个数组,例如:

Array = {France, Spain, France, France, Italy, Spain, Spain, Italy} 

我知道它的长度

index数组将是:

 index = {0, 1, 2, 3, 4, 5, 6, 7} 

现在,使用Arrays.sort(Array);对其进行Arrays.sort(Array);Arrays.sort(Array);

newArray会像:

 newArray = {France, France, France, Italy, Italy, Spain, Spain, Spain} 

newIndex将是:

 newIndex = {0, 2, 3, 4, 7, 1, 5, 6} 

问题是:如何从input数组中findnewIndex

提前致谢

不要对数组进行sorting。 对索引数组进行sorting,传入一个比较器,将比较值作为数组中的索引。 所以你最终得到了newIndex作为sorting的结果,并且从那里到实际项目的sorting数组是微不足道的。

诚然,这意味着以一种自定义的方式对整数数组进行sorting – 这意味着使用Integer[]和标准的Java库,或者具有“IntComparator”接口的第三方库可以与sort(int[], IntComparator)types的方法。

编辑:好的,这里是一个比较例子。 为了简单起见,我假设你只想sorting一个“原始”string数组…我不会打扰无效性testing。

 public class ArrayIndexComparator implements Comparator<Integer> { private final String[] array; public ArrayIndexComparator(String[] array) { this.array = array; } public Integer[] createIndexArray() { Integer[] indexes = new Integer[array.length]; for (int i = 0; i < array.length; i++) { indexes[i] = i; // Autoboxing } return indexes; } @Override public int compare(Integer index1, Integer index2) { // Autounbox from Integer to int to use as array indexes return array[index1].compareTo(array[index2]); } } 

你会这样使用它:

 String[] countries = { "France", "Spain", ... }; ArrayIndexComparator comparator = new ArrayIndexComparator(countries); Integer[] indexes = comparator.createIndexArray(); Arrays.sort(indexes, comparator); // Now the indexes are in appropriate order. 

用Java 8 Stream API实现这个简洁的方法,

 final String[] strArr = {"France", "Spain", "France"}; int[] sortedIndices = IntStream.range(0, strArr.length) .boxed().sorted((i, j) -> strArr[i].compareTo(strArr[j]) ) .mapToInt(ele -> ele).toArray(); 
 TreeMap<String,Int> map = new TreeMap<String,Int>(); for( int i : indexes ) { map.put( stringarray[i], i ); } 

现在通过迭代map.values()来按照sorting顺序检索索引,并通过map.keySet()获取string,或者通过map.entrySet()获取string索引对。

你可以这样做的一种方法是将原始索引和国家名称包装到一个单独的类中。 然后根据名称对数组进行sorting。 这样,您的原始索引将被保留。

我根据@ Skeet的代码做了以下。 我认为这是多一点OOPie。 我不知道。

 public static <T extends Comparable<T>> List<Integer> sortIndex(List<T> in) { ArrayList<Integer> index = new ArrayList<>(); for (int i = 0; i < in.size(); i++) { index.add(i); } Collections.sort(index, new Comparator<Integer>() { @Override public int compare(Integer idx1, Integer idx2) { return in.get(idx1).compareTo(in.get(idx2)); } }); return index; } 

而不是实现sorting和索引具有不同对象的比较器代码进来的类,原始数组中的对象必须实现Comparable接口。 似乎很多感兴趣的对象都有一个自然的顺序,并且已经实现了Comparable接口。

 public static void main(String[] args) { List<Integer> a1 = new ArrayList<>(Arrays.asList(2, 3, 9, 4, 1)); // Just pass in the list to have its indexes sorted by the natural ordering List<Integer> idx = sortIndex(a1); List<Double> a2 = new ArrayList<>(Arrays.asList(1.0, 5.3, 5.2, -3.1, 0.3)); idx = sortIndex(a2); List<numBits> a3 = new ArrayList<>(); for (int i = 0; i < 10; i++) { a3.add(new numBits(i)); } // If you need to sort the indexes of your own object, you must implement // the Comparable Interface. idx = sortIndex(a3); } static class numBits implements Comparable<numBits> { private int a; public numBits(int i) { a = i; } public String toString() { return Integer.toString(a); } // Sort by the total number of bits in the number. @Override public int compareTo(numBits that) { if (Integer.bitCount(this.a) < Integer.bitCount(that.a)) return -1; if (Integer.bitCount(this.a) > Integer.bitCount(that.a)) return 1; return 0; } } 

如果使用正值重复排列原始float数组或int数组的情况,那么与使用任何比较器相比,像下面这样的方法会产生好得多的(x3〜x4)速度:

 long time = System.currentTimeMillis(); for (int i = 0; i < iters; i++) { float[] array = RandomUtils.randomFloatArray(-1, 1, 3000); long[] valueKeyPairs = new long[array.length]; for (int j = 0; j < array.length; ++j) { valueKeyPairs[j] = (((long) Float.floatToIntBits(array[j])) << 32) | (j & 0xffffffffL); } Arrays.sort(valueKeyPairs); /**Then use this to retrieve the original value and index*/ //long l = valueKeyPairs[j]; //float value = Float.intBitsToFloat((int) (l >> 32)); //int index = (int) (l); } long millis = System.currentTimeMillis() - time; 

一开始就是这样映射它们的

 Map <Integer, String> map = new HashMap<Integer, String>(); map.put(0, "France"); map.put(1, "Spain"); map.put(2, "France"); 

然后按照这样的值对它们进行sorting,然后就可以知道它们的索引和值(键,值)只是打印地图

 Iterator mapIterator = map.keySet().iterator(); while (mapIterator .hasNext()) { String key = mapIterator.next().toString(); String value = map.get(key).toString(); System.out.println(key + " " + value); }