Java 如果存在重复的数组,如何相对于另一个数组对数组进行排序?

Java 如果存在重复的数组,如何相对于另一个数组对数组进行排序?,java,arrays,sorting,collections,stream,Java,Arrays,Sorting,Collections,Stream,如果存在唯一值,我可以根据另一个数组对数组进行排序。但由于我正在尝试对以下给定数组进行排序: 初始燃料[]={1,9,9,2,9,9}; 初始成本[]={2,6,5,4,3,1}; 我想对燃料阵列进行排序,然后又想根据燃料阵列对成本阵列进行排序。 我希望输出如下所示: final fuel[]={1,2,9,9,9}; 最终成本[]={2,4,6,5,3,1}; 下面是我的代码: 公共静态无效排序(列表c、列表f){ 列表cc=新阵列列表(c); 收集.分类(c); List al=新的Ar

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

初始燃料[]={1,9,9,2,9,9};
初始成本[]={2,6,5,4,3,1};
我想对燃料阵列进行排序,然后又想根据燃料阵列对成本阵列进行排序。
我希望输出如下所示:

final fuel[]={1,2,9,9,9};
最终成本[]={2,4,6,5,3,1};
下面是我的代码:

公共静态无效排序(列表c、列表f){
列表cc=新阵列列表(c);
收集.分类(c);
List al=新的ArrayList();
int i=0;
而(i

如何使用comparator以这种方式进行排序?另外,如何使用stream api实现同样的目标?

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

int[] fuel = { 1, 9, 9, 2, 9, 9 };
int[] cost = { 2, 6, 5, 4, 3, 1 };
这将创建类并根据燃料值对其进行排序,然后将其放入列表中

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)
您可以将各个值复制回列表,如下所示:

List<Integer> fuelList = fuelInfo.stream()
        .map(FuelInfo::getFuel).collect(Collectors.toList());
List<Integer> costList = fuelInfo.stream()
        .map(FuelInfo::getCost).collect(Collectors.toList());
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);
    }
}
使用以下命令:

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);

希望这就是你要找的

假设这两个数组的长度相同,您可以创建一个包含来自这些数组的元素对的映射条目列表,然后先按键再按值对该列表进行排序,或者您可以仅按键对其进行排序,然后按插入顺序对值进行排序:

Integer[]fuel={1,9,9,2,9,9,2};
整数[]成本={2,6,5,4,3,1,5};
List entryList=IntStream.range(0,fuel.length)
//创建带有一个条目“燃料成本”的地图
.mapToObj(i->Map.of(燃料[i],成本[i]))
//将所有条目展平到一个流中
.flatMap(map->map.entrySet().stream())
//分类条目
.排序(比较)
//首先按键-燃油-按升序排列
.比较((Map.Entry)->Entry.getKey())
//然后按价值-成本-降序排列,或不按
//第二个比较器,重复项按插入顺序排序
.thenComparing(Map.Entry::getValue,Comparator.reverseOrder())
//返回已排序的条目列表
.collect(Collectors.toList());
System.out.println(entryList);//[1=2, 2=5, 2=4, 9=6, 9=5, 9=3, 9=1]
//如果要替换数组的内容
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]


另请参见:

谢谢。是否有一种方法可以在不创建新类的情况下执行相同的操作。我想将这两个数组都保存在单独的arrayList中。希望你明白我的问题。如果你想在分类后保持燃料价值和成本的严格关联,就不要这样做。但请参阅我的修订解决方案,以便轻松地将它们复制回来。到个人列表。@KhushtarHussain我把我的答案和你想要的放在一起(希望如此),我切换到列表以符合你的编辑。
[1, 2, 9, 9, 9, 9]
[2, 4, 6, 5, 3, 1]

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);
    }
}
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]