我正在尝试根据列和值对2D数组进行排序,但从未得到我想要的结果。
public class SortColl {
public static void main(String args[]){
String[][] multi = new String [][]{
{"Josef", "cool"},
{"Josef", "bat"},
{"zeta", "doen"},
{"zeta", "up"},
{"root", "local"},
{"root", "region"}
};
Arrays.sort(multi, new Comparator<String[]>(){
@Override
public int compare(String[] first, String[] second){
final String time1 = first[0];
final String time2 = second[0];
return time1.compareTo(time2);
}
});
for (int i=0; i< multi.length; i++){
String[] row = multi[i];
for(int j=0; j<row.length;j++){
System.out.println(" , " + row[j] );
}
}
}
}
对于上述内容,我希望得到结果
{"Josef", "bat"},
{"Josef", "cool"},
{"root", "local"},
{"root", "region"}
{"zeta", "doen"},
{"zeta", "up"},
任何人都可以指导我吗?
答案 0 :(得分:3)
您可以使用比较器功能,但您必须理解2D阵列在内存中的表示方式。
String[][] multi = new String [][]{
{"Josef", "cool"},
{"Josef", "bat"},
{"zeta", "doen"}
};
这意味着multi是一个数组数组。 multi的第一个索引是一个内容为“Josef”和“cool”的数组。第二个“约瑟夫”和“蝙蝠”。等等。
更直观:
multi ----> [ ][ ][ ]
| | |
| | \->["zeta", "doen"]
| |
| \-> ["Josef"]["bat"]
|
\-> ["Josef"]["cool"]
使用Array.sort()
时,比较器接收一维数组作为参数。因此,当参数为String[] first, String[] second
然后在内存中时,您(当Array.sort()
函数正在执行第一步时)
first --> ["Josef"]["cool"]
second--> ["Josef"]["bat"]
因此,为了正确排序,您必须检查第一个元素。如果匹配,则检查第二个元素。因此我调整了你的比较器类;
Arrays.sort(multi, new Comparator<String[]>(){
@Override
public int compare(String[] first, String[] second){
// compare the first element
int comparedTo = first[0].compareTo(second[0]);
// if the first element is same (result is 0), compare the second element
if (comparedTo == 0) return first[1].compareTo(second[1]);
else return comparedTo;
}
});
这应该可以胜任。
答案 1 :(得分:1)
稍微修改您的排序机制
Arrays.sort(multi, new Comparator<String[]>(){
@Override
public int compare(String[] first, String[] second){
final String time1 = first[0];
final String time2 = second[0];
int compare = time1.compareTo(time2);
if(compare != 0){
return compare;
}else{
return first[1].compareTo(second[1]);
}
}
});
您也可以像在java 8中一样编写
Arrays.sort(multi, (first, second) -> {
final String time1 = first[0];
final String time2 = second[0];
int compare = time1.compareTo(time2);
if(compare != 0){
return compare;
}else{
return first[1].compareTo(second[1]);
}
})
答案 2 :(得分:0)
我能看到这样做的唯一方法是分离出左右列,对它们进行排序,然后重新加入。
String[][] multi = new String [][]{
{"Josef", "cool"},
{"Josef", "bat"},
{"zeta", "doen"},
{"zeta", "up"},
{"root", "local"},
{"root", "region"}
};
String [] left = new String[multi.length];
for (int i = 0; i < multi.length; i++) {
left[i] = multi[i][0];
}
Arrays.sort(left);
String [] right = new String[multi.length];
for (int i = 0; i < multi.length; i++) {
right[i] = multi[i][1];
}
Arrays.sort(right);
for (int i = 0; i < multi.length; i++) {
multi[i][0] = left[i];
multi[i][1] = right[i];
}
答案 3 :(得分:0)
如果您使用的是Java 8,那么您可以创建一个元素比较器并在您的排序中使用它:
private Comparator<String[]> byElement(int i) {
return Comparator.comparing(a -> a[i]);
}
Arrays.sort(multi, byElement(0).thenComparing(byElement(1)));
我个人认为这比实现自己的compareTo
方法更优雅。它还可以通过标准Comparator
方法而不是自定义代码将新元素添加到比较中,或者反转一个字段,或者使用标准DateTime e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 p12
11/1/2014 1772 1926 1852 1513 1713 1568 1721 1822 1665 1449 1874 347
11/2/2014 19884 20365 19799 18017 18394 19383 20089 19929 20277 19522 19882 3710
11/3/2014 28697 29692 28881 25031 26731 28207 29095 29109 29577 28714 28926 5614
11/4/2014 24906 26061 25174 21745 23623 24126 24954 25344 25679 24406 25288 4990
11/5/2014 9059 9821 9116 7546 8742 8530 8910 9372 9214 8227 9366 1734
11/6/2014 1396 1691 1569 1176 1353 1223 1347 1541 1355 1044 1580 282
11/7/2014 10039 10416 9902 8223 9667 9511 9877 10106 10180 9524 10138 1857
11/8/2014 26746 27694 27128 23694 25520 26351 27176 27155 27704 26979 26995 5155
11/9/2014 14797 15567 14818 13556 14499 14244 14899 14979 15225 14171 14929 2846
11/10/2014 26059 27443 26573 22844 24655 25538 26658 26690 27303 26094 26471 5304
方法处理第一个或最后一个等等。
答案 4 :(得分:0)
赞赏这是一篇旧文章,所以如果将来有人遇到这个问题
Arrays.sort(multi, (a,b) -> a[0].compareTo(b[0]));