In my Android app I store days of week in an int variable by using bit masking.
I'm using the following SparseIntArray to get the day flags for the corresponding days:
public static final SparseIntArray DAY_FLAGS = new SparseIntArray(7);
static {
DAYS.put(Calendar.MONDAY, 1);
DAYS.put(Calendar.TUESDAY, 2);
DAYS.put(Calendar.WEDNESDAY, 4);
DAYS.put(Calendar.THURSDAY, 8);
DAYS.put(Calendar.FRIDAY, 16);
DAYS.put(Calendar.SATURDAY, 32);
DAYS.put(Calendar.SUNDAY, 64);
}
I'd like to be able to create String from a mask, for example:
int value -
String
1 - "Mon"
42 - "Tue Thu Sat"
127 - "Mon Tue Wed Thu Fri Sat Sun"
For this I'm using the following method:
public static String maskToString(Context context, int mask, int firstDayOfWeek) {
List<Integer> dayList = new ArrayList<>(7);
// The idea is to iterate through the SparseIntArray and check
// if the bit in the mask is set for the particular day.
// If it is, add that day to the dayList.
for (int i = 0; i < DAY_FLAGS.size(); i++) {
if (isFlagSet(DAY_FLAGS.valueAt(i), mask)) {
dayList.add(DAY_FLAGS.keyAt(i));
}
}
// Sort the days by taking the first day of the week into account
Collections.sort(dayList, new DayComparator(firstDayOfWeek));
// This List will contain the individual Strings for the days
List<String> dayStringList = new ArrayList<>(dayList.size());
// dayToString() simply returns a String resource for a given day
for (Integer day : dayList) {
dayStringList.add(dayToString(context, day));
}
// join the individual Strings into a single String
return TextUtils.join(" ", dayStringList);
}
The isFlagSet() method simply checks if a given flag is set in a given mask:
private static boolean isFlagSet(int flag, int mask) {
return ((mask & flag) == flag);
}
My maskToString() method seems clumsy (mostly in terms of unnecessary(?) object creation). I believe it can be optimized, I just don't know how.
(I can use only Java 7 features, no Java 8)
I'd appreciate any advice.
EDIT:
One thing I came up with regarding optimization is to create a static final DayComparator instance and pass the firstDayOfWeek variable in a setter (instead of the constructor):
private static final DayComparator DAY_COMPARATOR = new DayComparator();
public static String maskToString(Context context, int mask, int firstDayOfWeek) {
List<Integer> dayList = new ArrayList<>(7);
for (int i = 0; i < DAY_FLAGS.size(); i++) {
if (isFlagSet(DAY_FLAGS.valueAt(i), mask)) {
dayList.add(DAY_FLAGS.keyAt(i));
}
}
// so we do not create a new object here every time the method is called
DAY_COMPARATOR.setFirstDayOfWeek(firstDayOfWeek);
Collections.sort(days, DAY_COMPARATOR);
List<String> dayStringList = new ArrayList<>(dayList.size());
for (Integer day : dayList) {
dayStringList.add(dayToString(context, day));
}
return TextUtils.join(" ", dayStringList);
}
What do you think? Any other suggestions?