我将忽略数据库方面,因为您声称要从数组中获取一个布尔原始值数组。
枚举、枚举集、枚举映射
在 Java 方面,您可以使用 Java 中功能强大的 enum 以及 EnumSet。
为所有时隙定义一个枚举。为简洁起见,我将只包括一些。我为每个枚举项添加了一个displayName 来获得更漂亮的标签。
enum QuarterHour {
T_0700_0715, T_0715_0730, T_0730_0745, T_0745_0800;
public String displayName;
public LocalTime start, stop;
private QuarterHour () {
// Soft-code the members of each enum item by parsing its name.
this.displayName = this.name ().replace ( "T_" , "" ).replace ( "_" , "-" );
String[] tokens = this.displayName.split ( "-" ); // Extract the start and stop times from the left and right parts of this string.
String t1 = tokens[ 0 ].substring ( 0 , 2 ) + ":" + tokens[ 0 ].substring ( 2 );
String t2 = tokens[ 1 ].substring ( 0 , 2 ) + ":" + tokens[ 1 ].substring ( 2 );
this.start = LocalTime.parse ( t1 );
this.stop = LocalTime.parse ( t2 );
System.out.println ( "Debug construction of each QuarterHour enum item: " + this.name () + " with displayName: " + this.displayName + " from " + this.start + " to " + this.stop );
}
}
Java 提供了非常快速和非常小的 EnumSet 和 EnumMap 类来收集 Enum 实例。每个分别是Set 和Map 的实现,就像任何其他实现一样。特殊之处在于,由于它们专用于Enum 实例,因此可以通过在内部使用bitmaps 对其进行高度优化。所以他们使用非常很少的内存并且执行速度非常快。
暂时忽略您的布尔数组,这里有一些示例代码展示了如何使用EnumSet 和EnumMap。
DayOfWeek
我们的地图使用内置的 DayOfWeek 枚举,代表每周 7 天(周一至周日)中的每一天。
java.time
DayOfWeek 枚举是 Java 8 及更高版本中内置的 java.time 框架的一部分。这些类取代了旧的麻烦的日期时间类,例如java.util.Date。见Oracle Tutorial。大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。
示例代码
在此示例中,我有工作日从 07:00 到 08:00(四个刻钟)全时开放,周末从 07:30 到 08:00(两个刻钟)半小时后开放。
EnumMap<DayOfWeek , EnumSet<QuarterHour>> days = new EnumMap<> ( DayOfWeek.class );
EnumSet quarterHoursWhenOpen = EnumSet.of ( QuarterHour.T_0700_0715 , QuarterHour.T_0715_0730 , QuarterHour.T_0730_0745 , QuarterHour.T_0745_0800 );
EnumSet quarterHoursWhenOpen2 = EnumSet.of ( QuarterHour.T_0730_0745 , QuarterHour.T_0745_0800 );
days.put ( DayOfWeek.MONDAY , quarterHoursWhenOpen );
days.put ( DayOfWeek.TUESDAY , quarterHoursWhenOpen );
days.put ( DayOfWeek.WEDNESDAY , quarterHoursWhenOpen );
days.put ( DayOfWeek.THURSDAY , quarterHoursWhenOpen );
days.put ( DayOfWeek.FRIDAY , quarterHoursWhenOpen );
days.put ( DayOfWeek.SATURDAY , quarterHoursWhenOpen2 );
days.put ( DayOfWeek.SUNDAY , quarterHoursWhenOpen2 );
转储到控制台。默认情况下,在我们的 QuarterHours 枚举上隐式调用的 toString 方法默认使用元素的名称。为了向您的用户展示,您可以调用我定义的displayName 方法,而不是调用内置的toString。 toString 方法被定义为用于“程序员友好”的字符串值,而不是面向用户的表示字符串。
System.out.println ( "days: " + days );
天:{MONDAY = [T_0700_0715,T_0715_0730,T_0730_0745,T_0745_0800],周二= [T_0700_0715,T_0715_0730,T_0730_0745,T_0745_0800],周三= [T_0700_0715,T_0715_0730,T_0730_0745,T_0745_0800],星期四= [T_0700_0715,T_0715_0730,T_0730_0745 , T_0745_0800], FRIDAY=[T_0700_0715, T_0715_0730, T_0730_0745, T_0745_0800], SATURDAY=[T_0730_0745, T_0745_0800], SUNDAY=[T_0730_0745]0}p>008
顺便说一下,这种起止时间的命名遵循了处理时间跨度的常用方法,称为“半开放”,其中开始是包含而结束是独占。
转化
我们剩下要做的就是在 EnumSet QuarterHours 和布尔数组之间来回转换。有关更多信息,请参阅我的问题:Convert between EnumSet and array of boolean values。在这里,我使用了简单的 for 循环方法,但请查看 Java 8 及更高版本中更紧凑的 Lambda 和流语法的其他答案。
以下代码在枚举上调用values 方法。令人讨厌的是,Enum 类中没有记录此方法,因为该方法是由编译器综合创建的,用于解决 this Question 中讨论的棘手内部技术问题。结果是该方法返回枚举中所有项目的数组。
警告:所有这些代码都未经测试,只运行一次。使用风险自负。
从 EnumSet 到数组
// From EnumSet to array of boolean primitives.
QuarterHour[] quarterHoursOfDay = QuarterHour.values ();
boolean[] quarterHoursIfOpen = new boolean[ quarterHoursOfDay.length ];
EnumSet<QuarterHour> enumSet = days.get ( DayOfWeek.SATURDAY );
for ( int i = 0 ; i < quarterHoursOfDay.length ; i ++ ) {
quarterHoursIfOpen[ i ] = enumSet.contains ( quarterHoursOfDay[ i ] );
}
转储到控制台。
System.out.println ( "For " + DayOfWeek.SATURDAY + " array quarterHoursIfOpen: " + Arrays.toString ( quarterHoursIfOpen ) );
对于 SATURDAY 数组 QuarterHoursIfOpen:[false, false, true, true]
从数组到 EnumSet
换个方向,从上面的布尔数组quarterHoursIfOpen 到下面名为enumSet2 的新EnumSet。
// From array of boolean to EnumSet.
EnumSet<QuarterHour> enumSet2 = EnumSet.noneOf ( QuarterHour.class );
QuarterHour[] quarterHoursOfDay2 = QuarterHour.values ();
for ( int i = 0 ; i < quarterHoursOfDay2.length ; i ++ ) {
boolean isOpen = quarterHoursIfOpen[ i ];
if ( isOpen ) {
enumSet2.add ( quarterHoursOfDay[ i ] );
}
}
转储到控制台。
System.out.println ( "enumSet2: " + enumSet2 );
枚举集2:[T_0730_0745,T_0745_0800]
生成源代码
这里是一些源代码,用于生成源代码以命名所有 24 小时值的四分之一小时枚举名称。
StringBuilder enums = new StringBuilder ();
LocalTime start = LocalTime.MIN;
for ( int i = 0 ; i < ( 24 * 4 ) ; i ++ ) {
if ( enums.length () > 0 ) {
enums.append ( " , " );
}
LocalTime stop = start.plusMinutes ( 15 );
String name = "T_" + start.toString () + "_" + stop.toString ();
name = name.replaceAll ( ":" , "" );
enums.append ( name );
// Setup next loop
start = stop;
}
System.out.println ( "enums: " + enums );
枚举:T_0000_0015,T_0015_0030,T_0030_0045,T_0045_0100,T_0100_0115,T_0115_0130,T_0130_0145,T_0145_0200,T_0200_0215,T_0215_0230,T_0230_0245,T_0245_0300,T_0300_0315,T_0315_0330,T_0330_0345,T_0345_0400,T_0400_0415,T_0415_0430,T_0430_0445,T_0445_0500,T_0500_0515,T_0515_0530,T_0530_0545 ,T_0545_0600,T_0600_0615,T_0615_0630,T_0630_0645,T_0645_0700,T_0700_0715,T_0715_0730,T_0730_0745,T_0745_0800,T_0800_0815,T_0815_0830,T_0830_0845,T_0845_0900,T_0900_0915,T_0915_0930,T_0930_0945,T_0945_1000,T_1000_1015,T_1015_1030,T_1030_1045,T_1045_1100,T_1100_1115,T_1115_1130,T_1130_1145,T_1145_1200 ,T_1200_1215,T_1215_1230,T_1230_1245,T_1245_1300,T_1300_1315,T_1315_1330,T_1330_1345,T_1345_1400,T_1400_1415,T_1415_1430,T_1430_1445,T_1445_1500,T_1500_1515,T_1515_1530,T_1530_1545,T_1545_1600,T_1600_1615,T_1615_1630,T_1630_1645,T_1645_1700,T_1700_1715,T_1715_1730,T_1730_174 5,T_1745_1800,T_1800_1815,T_1815_1830,T_1830_1845,T_1845_1900,T_1900_1915,T_1915_1930,T_1930_1945,T_1945_2000,T_2000_2015,T_2015_2030,T_2030_2045,T_2045_2100,T_2100_2115,T_2115_2130,T_2130_2145,T_2145_2200,T_2200_2215,T_2215_2230,T_2230_2245,T_2245_2300,T_2300_2315,T_2315_2330,T_2330_2345, T_2345_0000