根据第一个排序数组的索引对第二个数组进行排序

时间:2020-07-29 12:37:41

标签: java android arrays sorting

我有两个大小相同的数组。

ArrayList<ProfileClass> array1= new ArrayList<>()
ArrayList<Double> array2= new ArrayList<>()

array1 = {b,d,a,c}
array2 = {2.0,4.0,1.0,3.0}

现在我需要按降序对array2进行排序。
Collections.sort(array2, Collections.reverseOrder());
Expected result: {4.0,3.0,2.0,1.0}

因此,对每个值进行排序之前,这些值的索引与对排序后的值不同。但是,针对array2中的每个值更改索引,我希望array1针对array2中的每个值更改索引。

Final Expected result of array1: {d,c,b,a}

6 个答案:

答案 0 :(得分:1)

您可以通过按array2的值对索引(0、1、2、3)进行排序并将结果映射到array1的值来获得结果。

System.out.println("array1=" + array1);
System.out.println("array2=" + array2);
ArrayList<ProfileClass> sortedArray1 = IntStream.range(0, array2.size())
    .boxed()
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(i -> array2.get(i))))
    .map(i -> array1.get(i))
    .collect(Collectors.toCollection(ArrayList::new));
System.out.println("sorted array1=" + sortedArray1);

输出:

array1=[b, d, a, c]
array2=[2.0, 4.0, 1.0, 3.0]
sorted array1=[d, c, b, a]

或者您也可以这样做。

ArrayList<ProfileClass> sortedArray1 = IntStream.range(0, array2.size())
    .mapToObj(i -> new Object() {
        double sortKey = array2.get(i);
        ProfileClass value = array1.get(i);
    })
    .sorted(Collections.reverseOrder(Comparator.comparingDouble(obj -> obj.sortKey)))
    .map(obj -> obj.value)
    .collect(Collectors.toCollection(ArrayList::new));

答案 1 :(得分:0)

您应该创建一个临时Double arrayList。并且应该在排序之前保留array2的索引。

预期tmpArrayList = {1, 3, 0, 2}

然后,使用这些索引,您可以重新创建array1。

如果您不必使用array1作为链表,那么最好使用array1 = new ProfileList[];

在这里,我想说为什么有必要,您可以将另一个字段放到您的profileclass对象中,例如array2Place?并更新它。我不明白您实际上在这里想做什么。例如,array2的索引是否与array1有关?

答案 2 :(得分:0)

使用这两个数组创建一个Map,然后使用键(数组2)从地图中获取第一个数组(地图值数组1)。

//Map it
Map<Double, ProfileClass> map = IntStream.range(0, array2.size()).boxed()
        .collect(Collectors.toMap(i -> array2.get(i), i -> array1.get(i)));
Collections.sort(array2, Collections.reverseOrder());

//Create new array for array1
List<ProfileClass> array11 = new ArrayList<>();
for (Double d : array2) {
    array11.add(map.get(d));
}

System.out.println(array11);

答案 3 :(得分:0)

假设两个数组(尤其是第一个数组)都可以包含重复项,我建议采用以下解决方案

ProfileClass[] arr1 = new String[] { b,d,a,c };
double[] arr2 = new double[] { 2.0,4.0,1.0,3.0 };

List<Tuple<ProfileClass, Double>> list 
  = IntStream.range(0, arr2.length) // create a stream of all possible indexes
  .mapToObj(i -> new Tuple<ProfileClass, Double>(arr1[i], arr2[i])) // zip the two arrays by the index
  .sorted((a,b) -> Double.compare(a.getItem2(), b.getItem2())) // sort the stream according to the second array
  .collect(Collectors.toList());

// write the result back to the array
for (int i = 0; i < arr1.length; i++) {
  arr1[i] = list.get(i).getItem1();
  arr2[i] = list.get(i).getItem2();
}

这里的类Tuple定义为:

public class Tuple<T1, T2> {
  private T1 item1;
  private T2 item2;

  public Tuple(T1 item1, T2 item2) {
      this.item1 = item1;
      this.item2 = item2;
  }

  public T1 getItem1() { return item1; }
  public T2 getItem2() { return item2; }
}

答案 4 :(得分:0)

易于使用TreeMap快速排序订单。

TreeMap<Double, ProfileClass> map = new TreeMap<>();
    for (int i = 0; i < array1.size(); i++) {
        map.put(array2.get(i), array1.get(i));
    }
    final Collection< ProfileClass> sortedArray = map.descendingMap().values();
    System.out.println(sortedArray);

答案 5 :(得分:0)

如果您能够拥有同时包含两个值的类,则只需一种。

如果这不可能,请从@NiravHR检查解决方案,这似乎是合法的。

Object[][] expand(Object[] array){
      Object[][] result = new Object[array.length][];
      for(int i=0;i<array.length;i++){
          result[i] = (Object[])array[i];
      }
      return result;
    }