简体   繁体   English

基于Java中其他数组的排序数组

[英]Sorting array based on other array in java

I have 2 arrays in java 我在java中有2个数组

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

if I sort the int array in ascending order,it'll be : 如果我将int数组按升序排序,它将是:

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

now I want to sort the name array accordingly. 现在我要对名称数组进行相应的排序。 The output should be : 输出应为:

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

how can I maintain a relation? 我该如何维持关系? I've seen this link( Sort Array based on other Sorted Array ),but its for js 我看过这个链接( 基于其他排序数组的排序数组 ),但是它适用于js

You can create a custom class with the combined data, ie one integer variable and one string variable. 您可以使用组合数据创建一个自定义类,即一个整数变量和一个字符串变量。 This class would implement the Comparable interface and override its compareTo() method. 此类将实现Comparable接口,并重写其compareTo()方法。 Then create an array of objects of this class, and sort it using normal Arrays.sort() function of util library. 然后创建此类的对象数组,并使用util库的常规Arrays.sort()函数对其进行排序。

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

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

Usage: 用法:

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

Using Java 8 Streams API 使用Java 8 Streams API

You can build a stream of all valid indexes, sort that stream according to the num array and then map the indexes to the name values and collect them in a new array. 您可以构建所有有效索引的流,根据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]);

And if needed (due to name array passed as reference to be "sorted" in-place), just copy the sorted values to the original array: 并且,如果需要的话(由于传递了name数组作为引用以进行“排序”),只需将排序后的值复制到原始数组即可:

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

Note that this way the array num is left untouched. 请注意,这样数组num保持不变。


Using a custom implementation of Bubble Sort 使用冒泡排序的自定义实现

As already figured out by the asker and mentioned by Jayanand the task is also easily accomplished by swapping elements in both array simultaneously whenever the sorting algorithm instructs to do so. 正如问问者已经指出并由Jayanand提到的那样,只要排序算法指示这样做,就可以通过同时交换两个数组中的元素来轻松完成此任务。

An implementation that uses both arrays directly: 直接使用两个数组的实现:

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

If you want to keep the logic and the value access separated so that Bubble Sort can be used for virtually any flavour indexed data structure: 如果要保持逻辑和值访问分开,以便Bubble Sort实际上可以用于任何风味索引数据结构:

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

As the average complexity of Bubble Sort is O(n²) (see its description at Wikipedia ) it doesn't make much sense to rant about unnecessary integer boxing and unboxing here. 由于冒泡排序的平均复杂度为O(n²) (请参阅Wikipedia上的描述 ),所以在这里对不必要的整数装箱和拆箱进行谴责没有多大意义。


Using data objects 使用数据对象

Create a new class for objects keeping both num and name value: 为同时保留numname值的对象创建一个新类:

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

Now if you have eg a List<Item> items it can be easily sorted using: 现在,如果您有一个List<Item> items则可以使用以下命令轻松对其进行排序:

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

To create such a list from your arrays you could use (similarly to using Streams API for sorting): 要从数组中创建这样的列表,可以使用(类似于使用Streams API进行排序):

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

Summary 摘要

What could be considered the best solution heavily depends on the particular use case that you have. 最佳解决方案在很大程度上取决于您的特定用例。

If you have no choice but working with those two arrays because they are passed to you in the context of some API or project where you are unable to change the design Bubble Sort with customized comparison and swap operations is definitely to be considered as long as you don't have thounsands of values to be sorted in which case it will be extremely slow. 如果您别无选择,只能使用这两个数组,因为它们是在某个API或项目的上下文中传递给您的,因此您无法通过自定义比较和交换操作来更改设计Bubble Sort ,那么只要您能够没有要排序的值的值,在这种情况下,它将非常慢。

If you have the freedom to decide how the num/name-pairs can be modeled I strongly suggest to design a specific class for those as already pointed out by iavanish . 如果您可以自由决定如何对num / name-pairs进行建模,我强烈建议为iavanish指出的类设计一个特定的类。 Be sure to implement equals and hashCode accordingly and keep in mind that when also implementing the Comparable interface it should reflect the natural order which should be in sync with the equals method. 确保相应地实现equalshashCode ,并请记住,在同时实现Comparable接口时,它应反映应与equals方法同步的自然顺序 So when calling equals for two objects (5, a) and (5, b) and the result is false the compareTo method should not return 0. If you need a particular order that is not natural go for Comparator instead. 所以,当调用equals两个对象(5,a)和(5,B),结果是falsecompareTo如果你需要一个特定的顺序,是不是对自然的走法应该不会返回0 Comparator来代替。

Sorting using the Streams API is to be prefered when working with a large number of values so that the initialization and integer boxing/unboxing overhead can be disregarded. 使用大量值时,首选使用Streams API进行排序,这样可以忽略初始化和整数装箱/拆箱的开销。 In that case also .parallel() could additionally be used in order to gain even more speed. 在那种情况下,还可以额外使用.parallel()以获得更快的速度。

  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]

Sorry,it was easy : 对不起,很简单:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM