从星期一开始按升序对星期几名称的字符串列表进行排序

时间:2018-09-22 13:13:21

标签: java list calendar comparator

我有一个包含星期几名称,开始时间和结束时间的字符串列表,格式如下:

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);

有人可以建议这样做的最好方法吗?

谢谢

1 个答案:

答案 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

您使用的日期时间类SimpleDateFormatDateCalendar早已过时且设计欠佳,因此我不想使用它们。它们也不适合表示您的数据:一周中的一天和一天中的两次。相比之下,现代Java日期和时间API java.time的DayOfWeekLocalTime完全符合需求。 LocalTime是一天中没有日期,没有时区或UTC偏移量的时间。按照国际标准(ISO 8601)的规定,DayOfWeek枚举成员的自然顺序从星期一开始。

链接: Oracle tutorial: Date Time解释了如何使用java.time