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

我试图按字典顺序排序三个数组。 这些arrays通过一个公共arrays相互关联。 如果我certificate,它更容易解释:

int[] record = new int[4]; String [] colors = {"blue", "yellow", "red", "black"}; String [] clothes = {"shoes", "pants", "boots", "coat"}; 

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

未排序:

 Record Color Clothes 0 blue shoes 1 yellow pants 2 red boots 3 black coat 

按颜色排序:

 Record Color Clothes 3 black coat 0 blue shoes 2 red boots 1 yellow pants 

按衣服排序:

 Record Color Clothes 2 red boots 3 black coat 1 yellow pants 0 blue shoes 

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

任何帮助,将不胜感激!

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

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


用法

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

 List ids = Arrays.asList(0, 1, 2, 3); List colors = Arrays.asList("blue", "yellow", "red", "black"); List 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); 

输出:

 // 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] 

这里可以找到Ideone示例其中包括参数validation和测试用例。

 public static > void concurrentSort( final List key, List... lists){ // Create a List of indices List indices = new ArrayList(); for(int i = 0; i < key.size(); i++) indices.add(i); // Sort the indices list based on the key Collections.sort(indices, new Comparator(){ @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 swapMap = new HashMap(indices.size()); List swapFrom = new ArrayList(indices.size()), swapTo = new ArrayList(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)); } 

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

由于RecordColorClothes似乎属于一体,我建议将它们放在一个自定义对象中,例如

 public class ClothesItem { int record; String color; String clothes; } 

然后你可以让不同的Comparator来做不同的排序变体。

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

好吧,这是最终forms的样子。

 // ColorClothes.java import java.util.*; public class ColorClothes { public int record; public String color; public String clothes; public static void main(String[] args) { Initialize(); } public ColorClothes(int record, String color, String clothes) { this.record = record; this.color = color; this.clothes = clothes; } public static void Initialize() { List list = new ArrayList(); list = CreateList(); Sort(list, "Unsorted", 1); Sort(list, "\nSortedByColor", 2); Sort(list, "\nSortedByClothes", 3); Sort(list, "\nSortedByRecord", 4); } public static List CreateList() { List list = new ArrayList(); list.add(new ColorClothes(1, "blue ", "shoes")); list.add(new ColorClothes(0, "yellow", "pants")); list.add(new ColorClothes(3, "red ", "boots")); list.add(new ColorClothes(2, "black ", "coat")); return list; } public static void Print(List list) { for (ColorClothes item : list) { System.out.println(item.record + " " + item.color + " " + item.clothes); } } public static void Sort(List list, String string, int choice) { System.out.println(string + "\n"); switch (choice) { case 1: break; case 2: Collections.sort(list, new ColorComparator()); break; case 3: Collections.sort(list, new ClothesComparator()); break; case 4: Collections.sort(list, new RecordComparator()); break; } Print(list); } } // End class. 

 // ColorComparator.java import java.util.Comparator; class ColorComparator implements Comparator { public int compare(Object str1, Object str2) { String str1Color = ((ColorClothes)str1).color; String str2Color = ((ColorClothes)str2).color; return str1Color.compareTo(str2Color); } }// End class. 

 // ClothesComparator.java import java.util.Comparator; class ClothesComparator implements Comparator { public int compare(Object str1, Object str2) { String str1Clothes = ((ColorClothes)str1).clothes; String str2Clothes = ((ColorClothes)str2).clothes; return str1Clothes.compareTo(str2Clothes); } } // End class. 

 // RecordComparator.java import java.util.Comparator; public class RecordComparator implements Comparator { public int compare(Object rec1, Object rec2) { int rec1Rec = ((ColorClothes)rec1).record; int rec2Rec = ((ColorClothes)rec2).record; if(rec1Rec > rec2Rec) { return 1; } else if(rec1Rec < rec2Rec) { return -1; } else { return 0; } } }// End class. 

控制台输出

 Unsorted 1 blue shoes 0 yellow pants 3 red boots 2 black coat SortedByColor 2 black coat 1 blue shoes 3 red boots 0 yellow pants SortedByClothes 3 red boots 2 black coat 0 yellow pants 1 blue shoes SortedByRecord 0 yellow pants 1 blue shoes 2 black coat 3 red boots 

我不确定一次排序多个数组; 查看您使用的用例,这看起来像一个竞争者,其中所有3个属性可以组合成一个对象,然后对象数组可以以多种方式排序。

你确定需要3个arrays吗?

ColoredCloth数组是否适用于您:

 class ColoredCloth implements Comparable{ int id; String color; String cloth; } 

并定义几个Comparatorscolorcloth排序。

直接对数组进行排序。 索引所有数组并仅对所需数组的索引数组进行排序。 看看这篇SOpost中的解决方案。 这将使您的arrays保持一致。 我不确定是否可以很容易地将其推断为同步排序Narrays,但它应该让您了解如何解决问题,以防您希望将数据分布在多个arrays中。 正如几位人士已经指出的那样,将数据分组到一个对象中是一种很好的方法。

下面是我如何对两个或多个相同长度的字符串数组进行排序,以便第一个数组按顺序排列,其他数组与该顺序匹配:

 public static void order(String[]... arrays) { //Note: There aren't any checks that the arrays // are the same length, or even that there are // any arrays! So exceptions can be expected... final String[] first = arrays[0]; // Create an array of indices, initially in order. Integer[] indices = ascendingIntegerArray(first.length); // Sort the indices in order of the first array's items. Arrays.sort(indices, new Comparator() { public int compare(Integer i1, Integer i2) { return first[i1].compareToIgnoreCase( first[i2]); } }); // Sort the input arrays in the order // specified by the indices array. for (int i = 0; i < indices.length; i++) { int thisIndex = indices[i]; for (String[] arr : arrays) { swap(arr, i, thisIndex); } // Find the index which references the switched // position and update it with the new index. for (int j = i+1; j < indices.length; j++) { if (indices[j] == i) { indices[j] = thisIndex; break; } } } // Note: The indices array is now trashed. // The first array is now in order and all other // arrays match that order. } public static Integer[] ascendingIntegerArray(int length) { Integer[] array = new Integer[length]; for (int i = 0; i < array.length; i++) { array[i] = i; } return array; } public static  void swap(T[] array, int i1, int i2) { T temp = array[i1]; array[i1] = array[i2]; array[i2] = temp; } 

如果你想用其他类型的数组做这个,那么你需要稍微重构一下。 或者,对于要与字符串数组一起排序的整数数组,可以将整数转换为字符串。

我建议你创建一个类,如下所示

 class Dress { public int record; public String color; public String clothes; } 

保持礼服清单如下

 List dressCollection = new ArrayList(); 

根据颜色和衣服实施比较器。

 List resultBasedOnColor = Collections.sort(dressCollection, new Comparator() { public int compareTo(Dress obj1, Dress obj2) { return obj1.color.compareTo(obj2.color); } }); 

基于衣服的左排序作为问题所有者的练习。

将数据放入@SiB等自定义类中:

 class ColoredClothes { int id; String color; String cloth; } 

然后,将此类的每个实例放入一个TreeMap中,颜色为键(或布名取决于您要排序的内容):

 TreeMap sortedCloth= new TreeMap(); //loop through arrays and put new ColoredClothes into Map 

然后获取排序值,如下所示:

 Collection values = sortedCloth.values(); 

您可以使用values.iterator()按顺序遍历这些

谢谢你的帮助。

我是如此固定使用数组并对这些数组进行排序(因为这是我所要求的),我甚至没有考虑过创建对象。

使用这个简单的程序,它将允许您创建一个对象并对对象中的字段进行排序。 颜色和衣服只是我使用的一个例子。

这是我在下面完成的代码:

 // ColorClothes.java import java.util.*; public class ColorClothes { public int record; public String color; public String clothes; public static void main(String[] args) { Initialize(); } public static void Initialize() { ColorClothes item[] = new ColorClothes[4]; item[0] = new ColorClothes(); item[0].record = 0; item[0].color = "blue"; item[0].clothes = "shoes"; item[1] = new ColorClothes(); item[1].record = 1; item[1].color = "yellow"; item[1].clothes = "pants"; item[2] = new ColorClothes(); item[2].record = 2; item[2].color = "red"; item[2].clothes = "boots"; item[3] = new ColorClothes(); item[3].record = 3; item[3].color = "black"; item[3].clothes = "coat"; System.out.println("Unsorted"); for(int i = 0; i < item.length; i++) { System.out.println(item[i].record + " " + item[i].color + " " + item[i].clothes); } System.out.println("\nSorted By Color\n"); Arrays.sort(item, new ColorComparator()); for(int i = 0; i < item.length; i++) { System.out.println(item[i].record + " " + item[i].color + " " + item[i].clothes); } System.out.println("\nSorted By Clothes\n"); Arrays.sort(item, new ClothesComparator()); for(int i = 0; i < item.length; i++) { System.out.println(item[i].record + " " + item[i].color + " " + item[i].clothes); } } }// End class. // ColorComparator.java import java.util.Comparator; class ColorComparator implements Comparator { public int compare(Object str1, Object str2) { String str1Color = ((ColorClothes)str1).color; String str2Color = ((ColorClothes)str2).color; return str1Color.compareTo(str2Color); } }// End class. // ClothesComparator.java import java.util.Comparator; class ClothesComparator implements Comparator { public int compare(Object str1, Object str2) { String str1Clothes = ((ColorClothes)str1).clothes; String str2Clothes = ((ColorClothes)str2).clothes; return str1Clothes.compareTo(str2Clothes); } } // End class. 

控制台输出

 Unsorted 0 blue shoes 1 yellow pants 2 red boots 3 black coat Sorted By Color 3 black coat 0 blue shoes 2 red boots 1 yellow pants Sorted By Clothes 2 red boots 3 black coat 1 yellow pants 0 blue shoes 

我将添加另一个Comparator以允许稍后按记录/整数排序。 我还会更加浓缩代码,因此它不是一个大块,但我几乎完成了当天的工作。

正如其他人所建议的那样,更容易对对象进行排序,而不是同步对三个数组进行排序。

如果由于某种原因你必须坚持排序多个数组,可以使用以下方法 – 想法是实现自己的数组列表变体,它由三个数组而不是一个数组支持

 import java.util.AbstractList; import java.util.Collections; public class SortMultipleArrays extends AbstractList { //object representing tuple from three arrays private static class ClothesItem implements Comparable { int record; String color; String clothes; public ClothesItem(int record, String color, String clothes) { this.record = record; this.color = color; this.clothes = clothes; } @Override public int compareTo(ClothesItem o) { return this.color.compareTo(o.color); //sorting by COLOR } } private int[] records; private String[] colors; private String[] clothes; public SortMultipleArrays(int[] records, String[] colors, String[] clothes) { this.records = records; this.colors = colors; this.clothes = clothes; } @Override public Object get(int index) { return new ClothesItem(records[index], colors[index], clothes[index]); } @Override public int size() { return records.length; } @Override public Object set(int index, Object element) { ClothesItem item = (ClothesItem) element; ClothesItem old = (ClothesItem) get(index); records[index] = item.record; colors[index] = item.color; clothes[index] = item.clothes; return old; } public static void main(String[] args) { int[] record = {0,1,2,3}; String[] colors = {"blue", "yellow", "red", "black"}; String[] clothes = {"shoes", "pants", "boots", "coat"}; final SortMultipleArrays multipleArrays = new SortMultipleArrays(record, colors, clothes); Collections.sort(multipleArrays); System.out.println("Record Color Clothes"); for (int i = 0; i < record.length; i++) { System.out.println(String.format("%8s %8s %8s", record[i], colors[i], clothes[i])); } } } 

此实现基于AbstractList,可以更轻松地实现Collections.sort(...)所需的List接口。

请注意,此实现中可能隐藏了低效率: get(...)set(...)方法都在创建包装器对象的实例,这可能导致在排序较大的数组时创建的对象太多。

喜欢@ bcorso创建交换列表以排序任何其他List的想法。 这是一个更优化的版本,只使用2个数组而不是Map和3个ListArrays,只交换需要交换的索引:

 public static > void syncedSort(final List key, List... lists) { // Create an array of indices Integer[] indices = new Integer[key.size()]; for (int i = 0; i < indices.length; i++) indices[i] = i; // Sort the indices array based on the key Arrays.sort(indices, new Comparator() { @Override public int compare(Integer i, Integer j) { return key.get(i).compareTo(key.get(j)); } }); // Scan the new indices array and swap items to their new locations, // while remembering where original items stored. // Only swaps can be used since we do not know the type of the lists int[] prevSwaps = new int[indices.length]; for (int i = 0; i < indices.length; i++) { int k = indices[i]; while (i > k) k = prevSwaps[k]; if (i != k) { prevSwaps[i] = k; for (List list : lists) Collections.swap(list, i, k); } } } 
 import java.util.Arrays; Arrays.sort (int []) Arrays.sort (String []) 

这将排序字符串数组。