Сортировка списка строк с именами дней недели, начиная с понедельника в порядке возрастания - PullRequest
0 голосов
/ 22 сентября 2018

У меня есть список строк, содержащих имя дня недели, время начала и время окончания в следующем формате:

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 голосов
/ 24 сентября 2018

Мне бы стоило написать вспомогательный класс для этого.Я хочу сортировать объекты этого класса, а не строки.Я всегда могу преобразовать обратно в строки после сортировки.

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 давно устарели и плохо разработаны, поэтому я не хотел их использовать.Они также плохо подходят для представления ваших данных: день недели и два раза в день.В отличие от DayOfWeek и LocalTime из java.time, современного API даты и времени Java, точно соответствуют потребностям.LocalTime - это время суток без даты и без смещения часового пояса или UTC.И естественный порядок членов перечисления DayOfWeek начинается с понедельника, как гласит международный стандарт (ISO 8601).

Ссылка: Учебное пособие по Oracle: Дата Время объясняя, как использовать java.time.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...