【问题标题】:Sorting a list of strings with day-of-week names starting with Monday in ascending order以从星期一开始按升序对具有星期几名称的字符串列表进行排序
【发布时间】:2019-02-26 15:30:31
【问题描述】:

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

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

任何人都可以建议最好的方法吗?

谢谢

【问题讨论】:

  • 您尝试过什么,遇到过什么问题?我们更有可能帮助那些表现出一些努力的人,或者我们假设您希望我们为您做功课。如果你有一个几乎可以工作的例子,我建议你修改它来做你想做的事情。
  • 其他示例将 Sun 作为排序列表中的第一项,但是... 那么是什么阻止您修改示例以从星期一开始排序?
  • 我试过我试图修改的是使用比较器类进行排序,我已经尽力修改代码以对列表进行排序,但失败了。我已经编辑了我的问题以添加到目前为止的代码。
  • @Maxim:我已经编写了代码来使用 If 语句实现相同的功能,但如果可能的话,我想使用 Comparator 类。我在上面的问题中提供了代码。谢谢
  • 我建议你避免使用SimpleDateFormat 类。它不仅过时了,而且出了名的麻烦。今天我们在java.time, the modern Java date and time API 中做得更好。

标签: java list calendar comparator


【解决方案1】:

我觉得为此编写一个辅助类是值得的。我想对这个类的对象而不是字符串进行排序。我总是可以在排序后转换回字符串。

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

这个 sn-p 的输出是:

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

【讨论】:

    猜你喜欢
    • 2017-09-11
    • 2019-06-23
    • 1970-01-01
    • 2011-10-31
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多