可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In Java, I have a data in my array like the following
2009.07.25 20:24 Message A
2009.07.25 20:17 Message G
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 20:01 Message F
2009.07.25 21:08 Message E
2009.07.25 19:54 Message R
I would like to sort it based on the first column, so my final data can look like this
2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E
The first column is a date of format \"yyyy.MM.dd HH:mm\" and the second column is a String.
回答1:
Sort a two dimensional array based on one column
The first column is a date of format \"yyyy.MM.dd HH:mm\" and the second column is a String.
Since you say 2-D array, I assume \"date of format ...\" means a String. Here\'s code for sorting a 2-D array of String[][]:
import java.util.Arrays;
import java.util.Comparator;
public class Asdf {
public static void main(final String[] args) {
final String[][] data = new String[][] {
new String[] { \"2009.07.25 20:24\", \"Message A\" },
new String[] { \"2009.07.25 20:17\", \"Message G\" },
new String[] { \"2009.07.25 20:25\", \"Message B\" },
new String[] { \"2009.07.25 20:30\", \"Message D\" },
new String[] { \"2009.07.25 20:01\", \"Message F\" },
new String[] { \"2009.07.25 21:08\", \"Message E\" },
new String[] { \"2009.07.25 19:54\", \"Message R\" } };
Arrays.sort(data, new Comparator<String[]>() {
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
for (final String[] s : data) {
System.out.println(s[0] + \" \" + s[1]);
}
}
}
Output:
2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E
回答2:
class ArrayComparator implements Comparator<Comparable[]> {
private final int columnToSort;
private final boolean ascending;
public ArrayComparator(int columnToSort, boolean ascending) {
this.columnToSort = columnToSort;
this.ascending = ascending;
}
public int compare(Comparable[] c1, Comparable[] c2) {
int cmp = c1[columnToSort].compareTo(c2[columnToSort]);
return ascending ? cmp : -cmp;
}
}
This way you can handle any type of data in those arrays (as long as they\'re Comparable) and you can sort any column in ascending or descending order.
String[][] data = getData();
Arrays.sort(data, new ArrayComparator(0, true));
PS: make sure you check for ArrayIndexOutOfBounds
and others.
EDIT: The above solution would only be helpful if you are able to actually store a java.util.Date
in the first column or if your date format allows you to use plain String comparison for those values. Otherwise, you need to convert that String to a Date, and you can achieve that using a callback interface (as a general solution). Here\'s an enhanced version:
class ArrayComparator implements Comparator<Object[]> {
private static Converter DEFAULT_CONVERTER = new Converter() {
@Override
public Comparable convert(Object o) {
// simply assume the object is Comparable
return (Comparable) o;
}
};
private final int columnToSort;
private final boolean ascending;
private final Converter converter;
public ArrayComparator(int columnToSort, boolean ascending) {
this(columnToSort, ascending, DEFAULT_CONVERTER);
}
public ArrayComparator(int columnToSort, boolean ascending, Converter converter) {
this.columnToSort = columnToSort;
this.ascending = ascending;
this.converter = converter;
}
public int compare(Object[] o1, Object[] o2) {
Comparable c1 = converter.convert(o1[columnToSort]);
Comparable c2 = converter.convert(o2[columnToSort]);
int cmp = c1.compareTo(c2);
return ascending ? cmp : -cmp;
}
}
interface Converter {
Comparable convert(Object o);
}
class DateConverter implements Converter {
private static final DateFormat df = new SimpleDateFormat(\"yyyy.MM.dd hh:mm\");
@Override
public Comparable convert(Object o) {
try {
return df.parse(o.toString());
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
}
And at this point, you can sort on your first column with:
Arrays.sort(data, new ArrayComparator(0, true, new DateConverter());
I skipped the checks for nulls and other error handling issues.
I agree this is starting to look like a framework already. :)
Last (hopefully) edit: I only now realize that your date format allows you to use plain String comparison. If that is the case, you don\'t need the \"enhanced version\".
回答3:
Arrays.sort(yourarray, new Comparator() {
public int compare(Object o1, Object o2) {
String[] elt1 = (String[])o1;
String[] elt2 = (String[])o2;
return elt1[0].compareTo(elt2[0]);
}
});
回答4:
install java8 jdk+jre
use lamda expression to sort 2D array.
code:
import java.util.Arrays;
import java.util.Comparator;
class SortString {
public static void main(final String[] args) {
final String[][] data = new String[][] {
new String[] { \"2009.07.25 20:24\", \"Message A\" },
new String[] { \"2009.07.25 20:17\", \"Message G\" },
new String[] { \"2009.07.25 20:25\", \"Message B\" },
new String[] { \"2009.07.25 20:30\", \"Message D\" },
new String[] { \"2009.07.25 20:01\", \"Message F\" },
new String[] { \"2009.07.25 21:08\", \"Message E\" },
new String[] { \"2009.07.25 19:54\", \"Message R\" }
};
// this is applicable only in java 8 version.
Arrays.sort(data, (String[] s1, String[] s2) -> s1[0].compareTo(s2[0]));
// we can also use Comparator.comparing and point to Comparable value we want to use
// Arrays.sort(data, Comparator.comparing(row->row[0]));
for (final String[] s : data) {
System.out.println(s[0] + \" \" + s[1]);
}
}
}
output
2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E
回答5:
Assuming your array contains strings, you can use the following:
String[] data = new String[] {
\"2009.07.25 20:24 Message A\",
\"2009.07.25 20:17 Message G\",
\"2009.07.25 20:25 Message B\",
\"2009.07.25 20:30 Message D\",
\"2009.07.25 20:01 Message F\",
\"2009.07.25 21:08 Message E\",
\"2009.07.25 19:54 Message R\"
};
Arrays.sort(data, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
String t1 = s1.substring(0, 16); // date/time of s1
String t2 = s2.substring(0, 16); // date/time of s2
return t1.compareTo(t2);
}
});
If you have a two-dimensional array, the solution is also very similar:
String[][] data = new String[][] {
{ \"2009.07.25 20:17\", \"Message G\" },
{ \"2009.07.25 20:25\", \"Message B\" },
{ \"2009.07.25 20:30\", \"Message D\" },
{ \"2009.07.25 20:01\", \"Message F\" },
{ \"2009.07.25 21:08\", \"Message E\" },
{ \"2009.07.25 19:54\", \"Message R\" }
};
Arrays.sort(data, new Comparator<String[]>() {
@Override
public int compare(String[] s1, String[] s2) {
String t1 = s1[0];
String t2 = s2[0];
return t1.compareTo(t2);
}
});
回答6:
Check out the ColumnComparator. It is basically the same solution as proposed by Costi, but it also supports sorting on columns in a List and has a few more sort properties.
回答7:
Using Lambdas since java 8:
final String[][] data = new String[][] { new String[] { \"2009.07.25 20:24\", \"Message A\" },
new String[] { \"2009.07.25 20:17\", \"Message G\" }, new String[] { \"2009.07.25 20:25\", \"Message B\" },
new String[] { \"2009.07.25 20:30\", \"Message D\" }, new String[] { \"2009.07.25 20:01\", \"Message F\" },
new String[] { \"2009.07.25 21:08\", \"Message E\" }, new String[] { \"2009.07.25 19:54\", \"Message R\" } };
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> x[1])).toArray(String[][]::new);
System.out.println(Arrays.deepToString(out));
Output:
[[2009.07.25 20:24, Message A], [2009.07.25 20:25, Message B],
[2009.07.25 20:30, Message D], [2009.07.25 21:08, Message E],
[2009.07.25 20:01, Message F], [2009.07.25 20:17, Message G],
[2009.07.25 19:54, Message R]]