根据特定值排序 ArrayList<DayOfWeek>

Order an ArrayList<DayOfWeek> based on a specific value

我有一个 ArrayList<DayOfWeek> 让我们说 ["MONDAY","WEDNESDAY","FRIDAY"]

我的目的是根据一个DayOfTheWeek循环排序

输入:"WEDNESDAY"

排序列表:["WEDNESDAY","FRIDAY","MONDAY"]

列表保证从星期一到星期日排序。不能保证输入的日期在列表中,在这种情况下,排序从列表中存在的下一个值开始。

我建议使用与此类似的方法:

how to order Arrays value as circular format in java?

其中每个 DayOfWeek 都有自己的 ID 编号,对应于其在排序中的预期位置,因此您可以围绕这些编号旋转。

Collections#rotate

演示:

import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<DayOfWeek> list = new ArrayList<>(List.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY,
                DayOfWeek.THURSDAY, DayOfWeek.FRIDAY, DayOfWeek.SUNDAY));

        Collections.rotate(list, list.size() - list.indexOf(DayOfWeek.WEDNESDAY));

        System.out.println(list);
    }
}

输出:

[WEDNESDAY, THURSDAY, FRIDAY, SUNDAY, MONDAY, TUESDAY]

互动:

import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        List<DayOfWeek> list = new ArrayList<>(List.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY,
                DayOfWeek.THURSDAY, DayOfWeek.FRIDAY, DayOfWeek.SUNDAY));

        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter the day: ");
        String day = scanner.nextLine();

        try {
            Collections.rotate(list, list.size() - list.indexOf(DayOfWeek.valueOf(day.toUpperCase())));
            System.out.println(list);
        } catch (IllegalArgumentException e) {
            System.out.println("Invalid input");
        }
    }
}

样本运行:

Enter the day: wednesday
[WEDNESDAY, THURSDAY, FRIDAY, SUNDAY, MONDAY, TUESDAY]

其他答案已经给出了正确的思路:使用Collections.rotate()。这只是为了考虑评论中的信息:

The list is guaranteed to be sorted from Monday through Sunday. The input day is not guaranteed to be in the list, in this case the sorting starts from the next value present in the list.

    ArrayList<DayOfWeek> list  = new ArrayList<>(List.of(
            DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.FRIDAY));
    DayOfWeek input = DayOfWeek.TUESDAY;
    
    int indexOfDesiredFirstDay = Collections.binarySearch(list, input);
    if (indexOfDesiredFirstDay < 0) {
        indexOfDesiredFirstDay = -indexOfDesiredFirstDay - 1;
    }
    Collections.rotate(list, -indexOfDesiredFirstDay);
    
    System.out.println(list);

本例中的输出:

[WEDNESDAY, FRIDAY, MONDAY]

由于列表永远不会超过7个元素,我们不需要二分查找的效率,但是Collections.binarySearch()仍然是一个方便的方法来找到我们想要来的元素的索引先轮后。 rotate() 接受负旋转量,因此我们只需取反(反转符号)索引并将其传递给该方法。计算出的索引可能会超出列表的末尾,但是rotate()也可以处理,所以没关系。

由于输入列表中可能缺少输入日期,因此需要使用Collections.rotate排序完整的工作日列表,然后通过输入列表进行过滤:

public static List<DayOfWeek> orderWithDayFirst(DayOfWeek first, List<DayOfWeek> dows) {
    List<DayOfWeek> fullWeek = Arrays.asList(DayOfWeek.values());
    Collections.rotate(fullWeek, -first.ordinal());
    return fullWeek.stream().filter(dows::contains).collect(Collectors.toList());
}

测试:

// Sunday is available
System.out.println(orderWithDayFirst(
        DayOfWeek.SUNDAY,
        Arrays.asList(DayOfWeek.MONDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY, DayOfWeek.TUESDAY)));

System.out.println("====");

// No Friday
System.out.println(orderWithDayFirst(
        DayOfWeek.FRIDAY,
        Arrays.asList(DayOfWeek.MONDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY, DayOfWeek.TUESDAY)));

输出

[SUNDAY, MONDAY, TUESDAY, SATURDAY]
====
[SATURDAY, SUNDAY, MONDAY, TUESDAY]