我有一个包含星期几名称,开始时间和结束时间的字符串列表,格式如下:
Wednesday 13:00 to 14:30
Saturday 14:20 to 18:10
Monday 09:00 to 14:25
Saturday 11:00 to 12:30
Sunday 08:00 to 14:25
我需要按以下顺序对其进行排序
Monday 09:00 to 14:25
Wednesday 13:00 to 14:30
Saturday 11:00 to 12:30
Saturday 14:20 to 18:10
Sunday 08:00 to 14:25
我需要对列表进行排序,以使“星期几”从星期一开始按升序排列。并且,如果有多个记录具有相同的星期几,则开始时间也应按升序排列。其他示例将Sun作为排序列表中的第一项,但我需要Mon作为第一项
这是我到目前为止使用Comparator类的代码,该类将'Sun'列在列表的顶部:
public int solution(String inputStr) {
String [] timeArray = inputStr.split(System.getProperty("line.separator"));
//List<String> list = inputStr.split(System.getProperty("line.separator"));
Arrays.sort(timeArray);
for (String str: timeArray) {
System.out.println(str);
}
Comparator<String> dateComparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
try{
SimpleDateFormat format = new SimpleDateFormat("EEE");
Date d1 = format.parse(s1);
Date d2 = format.parse(s2);
if(d1.equals(d2)){
return s1.substring(s1.indexOf(" ") + 1).compareTo(s2.substring(s2.indexOf(" ") + 1));
}else{
Calendar cal1 = Calendar.getInstance(new Locale("en", "UK"));
Calendar cal2 = Calendar.getInstance(new Locale("en", "UK"));
//Calendar cal2 = Calendar.getInstance();
// cal1.setFirstDayOfWeek(Calendar.MONDAY);
// cal1.setFirstDayOfWeek(Calendar.MONDAY);
//cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal1.setTime(d1);
cal2.setTime(d2);
return cal1.get(Calendar.DAY_OF_WEEK) - cal2.get(Calendar.DAY_OF_WEEK);
}
}catch(ParseException pe){
throw new RuntimeException(pe);
}
}
};
ArrayList<String> arrList = new ArrayList<String>(Arrays.asList(timeArray));
ArrayList<Long> arrSlots = new ArrayList<Long>();
Collections.sort(arrList, dateComparator);
System.out.println(arrList);
有人可以建议这样做的最好方法吗?
谢谢
答案 0 :(得分:0)
我认为值得为此编写辅助类。我想对此类的对象而不是字符串进行排序。排序后,我总是可以转换回字符串。
public class WeeklySlot implements Comparable<WeeklySlot> {
private static DateTimeFormatter dowFormatter = DateTimeFormatter.ofPattern("EEEE", Locale.UK);
private static Comparator<WeeklySlot> comp = Comparator.comparing(WeeklySlot::getDay)
.thenComparing(WeeklySlot::getStart)
.thenComparing(WeeklySlot::getEnd);
private String original;
private DayOfWeek day;
private LocalTime start;
private LocalTime end;
public WeeklySlot(String input) {
original = input;
String[] fields = input.split("\\s+");
if (fields.length != 4) {
throw new IllegalArgumentException("Requiring four space separated fields");
}
day = DayOfWeek.from(dowFormatter.parse(fields[0]));
start = LocalTime.parse(fields[1]);
if (! fields[2].equals("to")) {
throw new IllegalArgumentException("Missing 'to' after start time");
}
end = LocalTime.parse(fields[3]);
}
public String getOriginalString() {
return original;
}
public DayOfWeek getDay() {
return day;
}
public LocalTime getStart() {
return start;
}
public LocalTime getEnd() {
return end;
}
@Override
public int compareTo(WeeklySlot other) {
return comp.compare(this, other);
}
}
现在排序非常简单:
String inputStr = "Wednesday 13:00 to 14:30\n"
+ "Saturday 14:20 to 18:10\n"
+ "Monday 09:00 to 14:25\n"
+ "Saturday 11:00 to 12:30\n"
+ "Sunday 08:00 to 14:25";
String[] timeArray = inputStr.split("\\R");
String[] sortedArray = Arrays.stream(timeArray)
.map(WeeklySlot::new)
.sorted()
.map(WeeklySlot::getOriginalString)
.toArray(String[]::new);
for (String result : sortedArray) {
System.out.println(result);
}
此代码段的输出为:
Monday 09:00 to 14:25
Wednesday 13:00 to 14:30
Saturday 11:00 to 12:30
Saturday 14:20 to 18:10
Sunday 08:00 to 14:25
您使用的日期时间类SimpleDateFormat
,Date
和Calendar
早已过时且设计欠佳,因此我不想使用它们。它们也不适合表示您的数据:一周中的一天和一天中的两次。相比之下,现代Java日期和时间API java.time的DayOfWeek
和LocalTime
完全符合需求。 LocalTime
是一天中没有日期,没有时区或UTC偏移量的时间。按照国际标准(ISO 8601)的规定,DayOfWeek
枚举成员的自然顺序从星期一开始。
链接: Oracle tutorial: Date Time解释了如何使用java.time
。