java java中如何对多个数组进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12164795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to sort multiple arrays in java
提问by 074Geodude
I'm trying to sort three arrays by lexicographical order. The arrays are related to each other by a common array. It's easier to explain if I demonstrate:
我正在尝试按字典顺序对三个数组进行排序。这些数组通过一个公共数组相互关联。如果我演示一下就更容易解释了:
int[] record = new int[4];
String [] colors = {"blue", "yellow", "red", "black"};
String [] clothes = {"shoes", "pants", "boots", "coat"};
When printed on the console, I would like them to be put in three columns similar to below:
在控制台上打印时,我希望将它们放在类似于下面的三列中:
Unsorted:
未分类:
Record Color Clothes
0 blue shoes
1 yellow pants
2 red boots
3 black coat
Sorted by Color:
按颜色排序:
Record Color Clothes
3 black coat
0 blue shoes
2 red boots
1 yellow pants
Sorted by Clothes:
按衣服分类:
Record Color Clothes
2 red boots
3 black coat
1 yellow pants
0 blue shoes
I found a previous answer similar to my scenario, but it compared integers instead of strings, and I'm having trouble using the compareTo()
method and Arrays.sort()
to arrive at my desired output.
我找到了与我的场景类似的先前答案,但它比较的是整数而不是字符串,并且我在使用该compareTo()
方法并Arrays.sort()
获得所需的输出时遇到了问题。
Any help would be appreciated!
任何帮助,将不胜感激!
回答by bcorso
In some cases it doesn't make much sense to create a new class just to do sorting.
在某些情况下,创建一个新类只是为了进行排序并没有多大意义。
Here, is a function that can be used to sort an any number of arbitrarily typed lists (List<?>
) based on a key list (List<T implements Comparable>
). Ideone Example here.
这是一个函数,可用于List<?>
根据键列表 ( List<T implements Comparable>
)对任意数量的任意类型列表 ( )进行排序。 此处为 Ideone 示例。
Usage
用法
Here is an example of how you can use the function to sort multiple lists of arbitrary types:
下面是一个示例,说明如何使用该函数对多个任意类型的列表进行排序:
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);
Output:
输出:
// 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]
Code
代码
An Ideone Example can be found herewhich includes validation of parameters and a test case.
可以在此处找到 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));
}
NOTE:The running time is O(mlog(m) + mN)
where m
is the length of the list and N
is the number of lists. Usually m >> N
so the running time is not more significant than sorting only the key O(mlog(m))
.
注:在运行时间O(mlog(m) + mN)
,其中m
是列表的长度,N
是列表的数目。通常m >> N
所以运行时间并不比只排序键更重要O(mlog(m))
。
回答by Keppil
Since Record
, Color
and Clothes
seem to belong together, I would suggest moving them together in a custom Object, eg
由于Record
,Color
并且Clothes
似乎属于一起,我建议将它们一起移动到自定义对象中,例如
public class ClothesItem {
int record;
String color;
String clothes;
}
Then you can make different Comparator
s to do the different variants of sorting.
然后你可以制作不同的Comparator
s来做不同的排序变体。
If you need to preserve your current structure with multiple arrays, @Jherico has a sorting solution herethat gets an array of the sorted indexes, which should make it trivial to get to your wanted result.
如果您需要使用多个数组保留当前结构,@Jherico 在这里有一个排序解决方案,可以获取排序索引的数组,这应该可以轻松获得您想要的结果。
回答by 074Geodude
Alright, here's what it looks like in final form.
好的,这是最终形式的样子。
// 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<ColorClothes> list = new ArrayList();
list = CreateList();
Sort(list, "Unsorted", 1);
Sort(list, "\nSortedByColor", 2);
Sort(list, "\nSortedByClothes", 3);
Sort(list, "\nSortedByRecord", 4);
}
public static List<ColorClothes> CreateList()
{
List<ColorClothes> 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<ColorClothes> list)
{
for (ColorClothes item : list)
{
System.out.println(item.record + " " + item.color + " " + item.clothes);
}
}
public static void Sort(List<ColorClothes> 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.
Console Output
控制台输出
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
回答by count0
Sort the arrays in-directly. Index all your arrays and sort only the index-array of the desired array. Take a look at the solution in this SO post. This will keep your arrays consistent. I'm not sure if it's easy to extrapolate this to sorting N-arrays in sync though, but it should give you an idea of how to approach the problem in case you want to stick with having your data distributed in multiple arrays. As several people already pointed out, grouping the data in a single object is a good approach.
直接对数组进行排序。索引所有数组并仅对所需数组的索引数组进行排序。看看这个SO post中的解决方案。这将使您的阵列保持一致。不过,我不确定将其推断为同步排序 N 数组是否容易,但是如果您想坚持将数据分布在多个数组中,它应该让您了解如何解决这个问题。正如一些人已经指出的那样,将数据分组到一个对象中是一种很好的方法。
回答by Bharat Sinha
I am not sure about sorting multiple arrays at once; looking at the use case used by you this looks like a contender where all 3 attributes can be combined into an object and then the array of objects can be sorted in multiple ways.
我不确定一次对多个数组进行排序;看看您使用的用例,这看起来像是一个竞争者,其中所有 3 个属性都可以组合成一个对象,然后可以以多种方式对对象数组进行排序。
Are you sure that you need to have 3 arrays?
你确定你需要有 3 个数组吗?
Does an array of ColoredCloth
would work for you like:
是否ColoredCloth
对您有用的数组如下:
class ColoredCloth implements Comparable<ColoredCloth>{
int id;
String color;
String cloth;
}
and define a couple of Comparators
to sort by color
and cloth
.
并定义几个Comparators
以按color
和排序cloth
。
回答by intrepidis
Here is how I sort two or more string arrays of the same length, so that the first array is in order and the other arrays match that order:
这是我对两个或多个相同长度的字符串数组进行排序的方法,以便第一个数组按顺序排列,其他数组与该顺序匹配:
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<Integer>()
{
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 <T> void swap(T[] array, int i1, int i2)
{
T temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
If you want to do this with arrays of other types then you will need to refactor this somewhat. Alternatively, for an integer array to be sorted along with string arrays you could convert the integers to strings.
如果你想用其他类型的数组来做这件事,那么你需要稍微重构一下。或者,对于要与字符串数组一起排序的整数数组,您可以将整数转换为字符串。
回答by brthornbury
Put the data into a custom class like @SiB:
将数据放入像@SiB 这样的自定义类中:
class ColoredClothes {
int id;
String color;
String cloth;
}
Then, put each instance of this class into a TreeMap with the color as the key (or cloth name depending what you want to sort by):
然后,将此类的每个实例放入一个以颜色为键的 TreeMap(或布料名称,取决于您要排序的内容):
TreeMap<String,ColoredClothes> sortedCloth= new TreeMap<String,ColoredClothes>();
//loop through arrays and put new ColoredClothes into Map
Then get the sorted values like so:
然后像这样得到排序的值:
Collection<ColoredClothes> values = sortedCloth.values();
You can iterate through these in order by using values.iterator()
您可以使用 values.iterator() 按顺序遍历这些
回答by jazzgil
Liked @bcorso's idea of creating swapping lists to sort any other List. Here's a bit more optimized version, that uses only 2 arrays instead of a Map and 3 ListArrays, and only swaps indexes that need swapping:
喜欢@bcorso 创建交换列表以对任何其他列表进行排序的想法。这是一个更优化的版本,它只使用 2 个数组而不是 Map 和 3 个 ListArrays,并且只交换需要交换的索引:
public static <T extends Comparable<T>> void syncedSort(final List<T> 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<Integer>() {
@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);
}
}
}
回答by sundar
I suggest you to create a class as below
我建议你创建一个类如下
class Dress {
public int record;
public String color;
public String clothes;
}
Maintain the list of dresses as below
保持礼服列表如下
List<Dress> dressCollection = new ArrayList<Dress>();
Implement comparator based on color and clothes.
实现基于颜色和衣服的比较器。
List<Dress> resultBasedOnColor = Collections.sort(dressCollection, new Comparator<Dress>() {
public int compareTo(Dress obj1, Dress obj2) {
return obj1.color.compareTo(obj2.color);
}
});
Left sorting based on clothes as exercise for question owner.
左排序基于衣服作为问题所有者的练习。
回答by 074Geodude
Thanks for the help guys.
谢谢你们的帮助。
I was so fixed on using arrays and sorting those arrays (since that's what was required of me), that I didn't even think about creating objects instead.
我非常专注于使用数组和对这些数组进行排序(因为这是我的要求),我什至没有考虑创建对象。
With this simple program, it'll allow you to create an object and sort the fields within the object. The colors and clothes were just an example I was using.
通过这个简单的程序,您可以创建一个对象并对对象中的字段进行排序。颜色和衣服只是我使用的一个例子。
Here's my completed code below:
这是我完成的代码如下:
// 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.
Console Output
控制台输出
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
I'll add another Comparator to allow sorting by record/integers later. I'll also condense the code more so it's not one big block, but I'm almost done with work for the day.
我将添加另一个比较器,以便稍后按记录/整数进行排序。我还将进一步压缩代码,使其不是一个大块,但我几乎完成了一天的工作。