基于java中的其他数组对数组进行排序

时间:2017-03-09 17:09:48

标签: java arrays sorting

我在java中有2个数组

int[] num={5,2,10,12,4};
String[] name={"a","b","g","c","r"};

如果我按升序对int数组进行排序,它将是:

int[] num={2,4,5,10,12};

现在我想相应地对名称数组进行排序。 输出应为:

String[] name={"b","r","a","g","c"};

我该如何保持关系? 我已经看到了这个链接(Sort Array based on other Sorted Array),但它是用于js

4 个答案:

答案 0 :(得分:1)

您可以使用组合数据创建自定义类,即一个整数变量和一个字符串变量。该类将实现Comparable接口并覆盖其compareTo()方法。然后创建这个类的对象数组,并使用util库的普通Arrays.sort()函数对其进行排序。

public class Data implements Comparable<Data> {
    int num;
    String name;

    @Override
    public int compareTo(Data data) {
        return this.num - data.num;
    }
}

用法:

Data[] data = new Data[5];
// initialize data
Arrays.sort(data)
// now the num will be sorted in ascending order and name will be shuffled accordingly

答案 1 :(得分:1)

使用Java 8 Streams API

您可以构建所有有效索引的流,根据num数组对该流进行排序,然后将索引映射到name值,并将它们收集到一个新数组中。

String[] nameSorted = IntStream.range(0, num.length).boxed()
        .sorted((i, j) -> Integer.compare(num[i], num[j]))
        .map(i -> name[i])
        .toArray(x -> new String[x]);

如果需要(由于name数组作为引用传递为“就地排序”),只需将已排序的值复制到原始数组:

System.arraycopy(nameSorted, 0, name, 0, name.length);

请注意,数组num保持不变。

使用冒泡排序

的自定义实现

正如提问者已经想到并由Jayanand提到的那样,只要排序算法指示这样做,任务也可以通过同时交换两个数组中的元素来轻松完成。

直接使用两个数组的实现:

for (int i = 0; i < num.length; i++) {
    for (int j = i + 1; j < num.length; j++) {
        if (num[i] > num[j]) {
            int tempNum = num[i];
            String tempName = name[i];
            num[i] = num[j];
            name[i] = name[j];
            num[j] = tempNum;
            name[j] = tempName;
        }
    }
}

如果您希望将逻辑和值访问分开,以便冒泡排序可用于几乎任何风味索引数据结构:

public static void bubbleSort(int length, IntBinaryOperator comparator,
        BiConsumer<Integer, Integer> swapOperation) {
    for (int i = 0; i < length; i++)
        for (int j = i + 1; j < length; j++)
            if (comparator.applyAsInt(i, j) > 0)
                swapOperation.accept(i, j);
}

bubbleSort(num.length, 
        (i, j) -> Integer.compare(num[i], num[j]), 
        (i, j) -> {
            int tempNum = num[i];
            String tempName = name[i];
            num[i] = num[j];
            name[i] = name[j];
            num[j] = tempNum;
            name[j] = tempName;
        });

由于冒泡排序的平均复杂度是 O(n²)(参见its description at Wikipedia),在这里咆哮不必要的整数装箱和拆箱没有多大意义。

使用数据对象

为保持numname值的对象创建一个新类:

class Item {
    int num;
    String name;
    Item(int num, String name) {
        this.num = num;
        this.name = name;
    }
}

现在,如果您有例如a List<Item> items可以使用以下方法轻松排序:

items.sort(Comparator.comparing(item -> item.num));

要从您可以使用的数组创建这样的列表(类似于使用Streams API进行排序):

List<Item> items = IntStream.range(0, num.length)
        .mapToObj(i -> new Item(num[i], name[i]))
        .collect(Collectors.toList());

摘要

可以认为最佳解决方案在很大程度上取决于您拥有的特定用例。

如果您别无选择,只能使用这两个数组,因为它们是在某些API或项目的上下文中传递给您的,您无法使用自定义比较和交换更改设计冒泡排序只要你没有要排序的值的数据,在这种情况下它将非常慢,就绝对要考虑操作。

如果您可以自由决定如何建模num / name-pair,我强烈建议为那些已经由 iavanish 指出的那些人设计一个特定的类。请务必相应地实施equalshashCode,并记住在实施Comparable界面时,它应该反映自然顺序,它应与之同步equals方法。因此,当为两个对象(5,a)和(5,b)调用equals并且结果为false时,compareTo方法应该返回0。如果您需要一个非常自然的特定订单,请选择Comparator

在处理大量值时,首选使用Streams API进行排序,以便可以忽略初始化和整数装箱/拆箱开销。在这种情况下,还可以使用.parallel()以获得更快的速度。

答案 2 :(得分:0)

  int[] num={5,2,10,12,4};
  String[] name={"a","b","g","c","r"};

  // During sorting int array...
  //Use indexes to switch the characters as well from     string array
  //Eg. If 2 from int array is shifting at index 0 from index 1 
 //Then also shift String[1] to String [0]

答案 3 :(得分:0)

抱歉,这很简单:

int[] num={5,2,10,12,4};
String[] name={"a","b","g","c","r"};
int tempNum;
String tempName;

for (int i = 0; i < num.length; i++) 
        {
            for (int j = i + 1; j < num.length; j++) 
            {
                if (num[i] > num[j]) 
                {
                    tempNum = num[i];
                    tempName=name[i];

                    num[i] = num[j];
                    name[i] = name[j];

                    num[j] = tempNum;
                    name[j] = tempName;
                }
            }
        }