如何在java中对多个数组进行排序

074*_*ude 20 java arrays sorting

我试图按字典顺序对三个数组进行排序.阵列通过公共阵列彼此相关.如果我证明,它更容易解释:

int[] record = new int[4];
String [] colors = {"blue", "yellow", "red", "black"};
String [] clothes = {"shoes", "pants", "boots", "coat"};
Run Code Online (Sandbox Code Playgroud)

在控制台上打印时,我希望将它们放在类似下面的三列中:

未排序:

Record  Color   Clothes
0       blue    shoes
1       yellow  pants
2       red     boots
3       black   coat
Run Code Online (Sandbox Code Playgroud)

按颜色排序:

Record  Color   Clothes
3       black   coat
0       blue    shoes
2       red     boots
1       yellow  pants
Run Code Online (Sandbox Code Playgroud)

按衣服排序:

Record  Color   Clothes
2       red     boots
3       black   coat
1       yellow  pants
0       blue    shoes
Run Code Online (Sandbox Code Playgroud)

我发现了一个类似于我的场景的先前答案,但是它比较了整数而不是字符串,而且我在使用该compareTo()方法时遇到了麻烦并且Arrays.sort()达到了我想要的输出.

任何帮助,将不胜感激!

bco*_*rso 8

在某些情况下,创建一个新类只是为了进行排序没有多大意义.

这里,是一个函数,可用于List<?>根据键列表(List<T implements Comparable>)对任意数量的任意类型列表()进行排序. 这里是Ideone示例.


用法

下面是一个如何使用该函数对任意类型的多个列表进行排序的示例:

List<Integer> ids = Arrays.asList(0, 1, 2, 3);
List<String> colors = Arrays.asList("blue", "yellow", "red", "black");
List<String> clothes = Arrays.asList("shoes", "pants", "boots", "coat");

// Sort By ID
concurrentSort(ids, ids, colors, clothes);

// Sort By Color
concurrentSort(colors, ids, colors, clothes);

// Sort By Clothes
concurrentSort(clothes, ids, colors, clothes);
Run Code Online (Sandbox Code Playgroud)

输出:

// Sorted By ID:
ID:      [0, 1, 2, 3]
Colors:  [blue, yellow, red, black]
Clothes: [shoes, pants, boots, coat]

// Sorted By Color:
ID:      [3, 0, 2, 1]
Colors:  [black, blue, red, yellow]
Clothes: [coat, shoes, boots, pants]

// Sorted By Clothes:
ID:      [2, 3, 1, 0]
Colors:  [red, black, yellow, blue]
Clothes: [boots, coat, pants, shoes]
Run Code Online (Sandbox Code Playgroud)

这里可以找到Ideone示例,其中包括参数验证和测试用例.

public static <T extends Comparable<T>> void concurrentSort(
                                        final List<T> key, List<?>... lists){
    // Create a List of indices
    List<Integer> indices = new ArrayList<Integer>();
    for(int i = 0; i < key.size(); i++)
        indices.add(i);

    // Sort the indices list based on the key
    Collections.sort(indices, new Comparator<Integer>(){
        @Override public int compare(Integer i, Integer j) {
            return key.get(i).compareTo(key.get(j));
        }
    });

    // Create a mapping that allows sorting of the List by N swaps.
    // Only swaps can be used since we do not know the type of the lists
    Map<Integer,Integer> swapMap = new HashMap<Integer, Integer>(indices.size());
    List<Integer> swapFrom = new ArrayList<Integer>(indices.size()),
                  swapTo   = new ArrayList<Integer>(indices.size());
    for(int i = 0; i < key.size(); i++){
        int k = indices.get(i);
        while(i != k && swapMap.containsKey(k))
            k = swapMap.get(k);

        swapFrom.add(i);
        swapTo.add(k);
        swapMap.put(i, k);
    }

    // use the swap order to sort each list by swapping elements
    for(List<?> list : lists)
        for(int i = 0; i < list.size(); i++)
            Collections.swap(list, swapFrom.get(i), swapTo.get(i));
}
Run Code Online (Sandbox Code Playgroud)

注:在运行时间O(mlog(m) + mN),其中m是列表的长度,N是列表的数目.通常m >> N所以运行时间并不比仅对键进行排序更重要O(mlog(m)).


Kep*_*pil 7

因为Record,Color并且Clothes似乎属于一起,我建议将它们一起移动到自定义对象中,例如

public class ClothesItem {
    int record;
    String color;
    String clothes;
}  
Run Code Online (Sandbox Code Playgroud)

然后你可以做出不同的Comparators来做不同的排序变体.

如果您需要使用多个数组保留当前结构,@ Jackson在这里有一个排序解决方案,它可以获得一系列已排序的索引,这样可以轻松获得您想要的结果.

  • 如果我们查看提供的示例,"记录"值也是相关的,也需要排序.所以可能"id"也需要作为对象的一部分添加到类中(类似于@SiB答案).否则,即使在按颜色或衣服分类后仍需要更多的工作,以保持正确的索引.那就是如果OP选择这种方法超过你列出的第二种方法. (2认同)