Given we can determine the first day of the week by soft-coding with Locale
:
DayOfWeek firstDayOfWeek = WeekFields.of( Locale.US ).getFirstDayOfWeek() ; // Sunday-Saturday.
… and given that Java comes with a built-in enum defining days of the week, DayOfWeek:
DayOfWeek[] dows = DayOfWeek.values() ; // Monday-Sunday
How can we create another array or a list of whose elements are the DayOfWeek
enum objects rearranged in order defined by our specified locale?
CodePudding user response:
tl;dr
Collections.rotate(
new ArrayList<> ( List.of( DayOfWeek.values() ) ) , // Actually, you would instantiate elsewhere and pass here.
DayOfWeek.MONDAY.ordinal() - WeekFields.of( Locale.US ).getFirstDayOfWeek().ordinal()
)
Details
Fortunately, you need not do the list-rotation work yourself. The Collections
utility class offers a rotate
method. Pass your list along with an offset.
To quote the Javadoc:
Rotates the elements in the specified list by the specified distance. After calling this method, the element at index i will be the element previously at index (i - distance) mod list.size(), for all values of i between 0 and list.size()-1, inclusive. (This method has no effect on the size of the list.)
For example, suppose list comprises [t, a, n, k, s]. After invoking Collections.rotate(list, 1) (or Collections.rotate(list, -4)), list will comprise [s, t, a, n, k].
final List< DayOfWeek > iso8601 = List.of( DayOfWeek.values() ) ; // Monday-Sunday, defined in ISO 8601 standard.
List< DayOfWeek > localeOrder = new ArrayList<>( iso8601 ) ; // Duplicate the list of DayOfWeek objects.
Locale locale = Locale.US ;
DayOfWeek localeFirstDayOfWeek = WeekFields.of( locale ).getFirstDayOfWeek() ; // Sunday-Saturday.
int distance = DayOfWeek.MONDAY.ordinal() - localeFirstDayOfWeek.ordinal() ;
Collections.rotate( localeOrder , distance ) ;
Dump to console.
System.out.println( iso8601 ) ;
System.out.println( localeOrder ) ;
System.out.println( distance ) ;
See that code run at Ideone.com.
[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
[SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
-6
Or more briefly:
List< DayOfWeek > localeOrder = new ArrayList< DayOfWeek > ( List.of( DayOfWeek.values() ) ) ;
Collections.rotate(
localeOrder ,
DayOfWeek.MONDAY.ordinal() - WeekFields.of( Locale.US ).getFirstDayOfWeek().ordinal()
) ;
See this code run at Ideone.com.
[SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
CodePudding user response:
Here's how it can be done using List.subList()
and Stream.concat()
.
The core idea
The rotated list can be constructed from two parts:
- From the first day of the week to Sunday (inclusive);
- From Monday to the first day of the week (exclusive). In case when the first day of the week is Monday, the second part would be empty.
That's how implementation might look like:
DayOfWeek firstDayOfWeek = WeekFields.of(Locale.US).getFirstDayOfWeek(); // the first Day of Week
List<DayOfWeek> initial = new ArrayList<>(EnumSet.allOf(DayOfWeek.class)); // initial list of Days of Week ordered according to ISO-8601
List<DayOfWeek> rotated = Stream.concat(
initial.subList(firstDayOfWeek.ordinal(), DayOfWeek.SUNDAY.ordinal() 1).stream(), // from the firstDayOfWeek to Sunday inclusive
initial.subList(DayOfWeek.MONDAY.ordinal(), firstDayOfWeek.ordinal()).stream() // from Monday to the firstDayOfWeek exclusive
).toList();
rotated.forEach(System.out::println); // printing the result
Output:
SUNDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY