java—如果存在重复的数组,如何根据另一个数组对数组进行排序?

oymdgrw7  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(507)

如果有唯一的值,我可以根据另一个数组对数组进行排序。但由于我正在尝试对以下给定数组排序:

initial fuel[]={1,9,9,2,9,9};
initial cost[]={2,6,5,4,3,1};

我想对燃料阵列进行排序,然后又想对燃料阵列的成本阵列进行排序。
我希望输出如下:

final fuel[]={1,2,9,9,9,9};
final cost[]={2,4,6,5,3,1};

下面是我的代码:

public static void sort(List<Integer> c, List<Integer> f) {
    List<Integer> cc = new ArrayList<>(c);
    Collections.sort(c);

    List<Integer> al = new ArrayList<>();

    int i = 0;
    while (i < c.size()) {
        int temp = c.get(i);
        int index = cc.indexOf(temp);
        al.add(f.get(index));

        cc.remove(index);
        f.remove(index);

        i++;
    }

    for (int value : c)
        System.out.print(value + " ");
    System.out.println();
    for (int value : al)
        System.out.print(value + " ");
}

如何使用比较器以这种方式进行排序?同样的,如何使用流api?

2sbarzqh

2sbarzqh1#

如果您总是想将给定的燃料值与成本相关联,那么我建议您创建一个类来容纳它们。这将允许正确排序,同时保持两个值在一起。

int[] fuel = { 1, 9, 9, 2, 9, 9 };
int[] cost = { 2, 6, 5, 4, 3, 1 };

这将创建类并基于fuel值对其进行排序,并将其放入列表中。

List<FuelInfo> fuelInfo =
        // generate array indices
        IntStream.range(0, fuel.length)

        // create the objects 
        .mapToObj(i -> new FuelInfo(fuel[i], cost[i]))

        // sort them based on fuel value 
        .sorted(Comparator.comparing(FuelInfo::getFuel))

        // put them in a list.
        .collect(Collectors.toList());

fuelInfo.forEach(System.out::println)

印刷品

[1, 2]
[2, 4]
[9, 6]
[9, 5]
[9, 3]
[9, 1]

您可以将各个值复制回列表,如下所示:

List<Integer> fuelList = fuelInfo.stream()
        .map(FuelInfo::getFuel).collect(Collectors.toList());
List<Integer> costList = fuelInfo.stream()
        .map(FuelInfo::getCost).collect(Collectors.toList());

如果您想保持副本的默认顺序,那么这将起作用,因为java中的排序是稳定的(在比较equals值时保持插入顺序)。其工作原理是根据燃料阵列的值对索引进行排序,然后使用排序后的索引以正确排序的顺序构建成本列表。

Comparator<Integer> comp = (a,b)->Integer.compare(fuel[a],fuel[b]);

Comparator<Integer> comp =
        (a, b) -> Integer.compare(fuel[a], fuel[b]);

List<Integer> sortedFuel = Arrays.stream(fuel).sorted()
        .boxed().collect(Collectors.toList());

List<Integer> sortedCost = IntStream.range(0, fuel.length)
        .boxed().sorted(comp).map(a -> cost[a])
        .collect(Collectors.toList());

System.out.println(sortedFuel);
System.out.println(sortedCost);

印刷品

[1, 2, 9, 9, 9, 9]
[2, 4, 6, 5, 3, 1]

fuelinfo类

class FuelInfo{
    private int fuelAmt;
    private int cost;
    public FuelInfo(int fuel, int cost) {
        this.fuelAmt = fuel;
        this.cost = cost;
    }
    public int getFuel() {
        return fuelAmt;
    }
    public int getCost() {
        return cost;
    }
    public String toString() {
        return String.format("[%s, %s]", fuelAmt, cost);
    }
}
ukqbszuj

ukqbszuj2#

使用以下选项:

Integer[] fuel = { 1, 9, 9, 2, 9, 9 };
Integer[] cost = { 2, 6, 5, 4, 3, 1 };
// Map each fuel number to a list of costs, keeps in order
// meaning that 9 will point to [6, 5, 3, 1] which is what
// we want.
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < fuel.length; i++) {
    if (!map.containsKey(fuel[i])) map.put(fuel[i], new ArrayList<>());
    map.get(fuel[i]).add(cost[i]);
}
List<Integer> sortedFuel = Arrays.asList(fuel);
Collections.sort(sortedFuel);
List<Integer> rearrangedCost = new ArrayList<>();
for (int val : sortedFuel) {
    // Get the first value of the mapping, which is the first that
    // appears in cost
    rearrangedCost.add(map.get(val).get(0));
    map.get(val).remove(0);
}
System.out.println("final fuel = " + sortedFuel);
System.out.println("final fuel = " + rearrangedCost);

输出:

final fuel = [1, 2, 9, 9, 9, 9]
final fuel = [2, 4, 6, 5, 3, 1]

希望这就是你要找的!

5sxhfpxr

5sxhfpxr3#

假设这两个数组的长度相同,可以创建一个包含这些数组中的元素对的Map项列表,然后先按键再按值对该列表进行排序,也可以仅按键对其进行排序,然后按插入顺序对值进行排序:

Integer[] fuel = {1, 9, 9, 2, 9, 9, 2};
Integer[] cost = {2, 6, 5, 4, 3, 1, 5};

List<Map.Entry<Integer, Integer>> entryList = IntStream.range(0, fuel.length)
        // create a Map with one entry 'fuel-cost'
        .mapToObj(i -> Map.of(fuel[i], cost[i]))
        // flatten all entries into one stream
        .flatMap(map -> map.entrySet().stream())
        // sorting entries
        .sorted(Comparator
                // first by key - fuel - in ascending order
                .comparing((Map.Entry<Integer, Integer> entry) -> entry.getKey())
                // then by value - cost - in descending order, or without a
                // second comparator, duplicates are sorted in insertion order
                .thenComparing(Map.Entry::getValue, Comparator.reverseOrder()))
        // return sorted list of entries
        .collect(Collectors.toList());

System.out.println(entryList); // [1=2, 2=5, 2=4, 9=6, 9=5, 9=3, 9=1]
// if you want to replace the contents of the arrays
IntStream.range(0, entryList.size()).forEach(i -> {
    fuel[i] = entryList.get(i).getKey();
    cost[i] = entryList.get(i).getValue();
});

System.out.println(Arrays.toString(fuel)); // [1, 2, 2, 9, 9, 9, 9]
System.out.println(Arrays.toString(cost)); // [2, 5, 4, 6, 5, 3, 1]

另请参见:基于多个字段收集ID列表

相关问题