店铺开店时间

时间:2014-04-16 10:56:33

标签: java android

这更像是一个应用程序设计问题,请原谅我,如果它不相关。

我正在处理的应用程序旨在显示该区域中哪些商店是开放的,我不确定存储此信息的最佳方式是什么。我从数据库中获取信息(我没有设计),它提供了一系列布尔值,用于确定商店在此期间是否开放。每个布尔值表示15分钟的时隙,例如07:00-07:15

这可以分为几天而不是特定的日期,例如商店可能会在周一至周五09:00-17:00但周六09:00-20:00开放,所以我保留的模型必须知道什么这一天但不一定是约会。

我不确定的是如何存储所有这些以便于查找的速度/速度,因为我希望视图能够实时更新(商店从打开变为关闭而不刷新)。我考虑过向DB添加一个表,其中包含任何商店的开放时间(使用适当的时间和日期),然后让SQLite完成所有艰苦的工作,允许Java假设商店已关闭,除非它获得记录但是感觉有点笨重,因为以某种方式把开放时间留在记忆中可能会更好。

你能给予的任何帮助都很棒。

2 个答案:

答案 0 :(得分:2)

我认为您的数据库看起来像这样:

("Bob's Bakery", [0,0,1,1,1,1, ... ])
("Aunt McGee's Gun-O-Rama", [0,0,0,0,1,1, ... ])
....

在上面的例子中,我定义了位阵列从上午07:00开始。 “......”表示我的懒惰一直持续到中午12:00:)

您可以使用该数据填充哈希映射,因此您最终会得到“15分钟开始”到“开放商店”的映射。像这样的东西(简单的伪代码可视化我的想法):

openShops = {
   ("07:30",{"Bob's Bakery"}),
   ("07:45",{"Bob's Bakery"}),      
   ("08:00",{"Bob's Bakery","Aunt McGee's Gun-O-Rama"}),
   ("08:15",{"Bob's Bakery","Aunt McGee's Gun-O-Rama"}),
   ...
}

这样您只需计算当前15分钟插槽的开头并执行一次查找。假设您想要在08:02开设商店,那么您只需将分钟数除以15(无余数),并将结果用作查询中分钟的值:

2 div 15 = 0→08:00→openShops.get("08:00")("Bob's Bakery","Aunt McGee's Gun-O-Rama")

答案 1 :(得分:2)

我将忽略数据库方面,因为您声称要从数组中获取布尔基元值数组。

Enum,EnumSet,EnumMap

在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提供非常快速且非常小的EnumSetEnumMap类来收集Enum个实例。与任何其他实现一样,每个都分别是SetMap的实现。特别之处在于,因为它们专用于Enum个实例,所以可以通过内部使用bitmaps对其进行高度优化。因此,他们使用 非常小内存非常快速地执行

暂时忽略您的布尔数组,以下是一些示例代码,说明如何使用EnumSetEnumMap

DayOfWeek

我们的地图使用内置的DayOfWeek枚举,代表星期一至星期日的七天中的每一天。

java.time

DayOfWeek枚举是Java 8及更高版本中内置的java.time框架的一部分。这些类取代了旧的麻烦的日期时间类,如java.util.Date。见Oracle Tutorial。许多java.time功能都被反向移植到Java 6& ThreeTen-Backport中的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 );

转储到控制台。默认情况下,默认情况下,我们的toString枚举隐式调用QuarterHours方法使用元素的名称。要向您的用户展示,您可以调用我定义的displayName方法,而不是调用内置的toStringtoString方法定义为&#34;程序员友好&#34;字符串值而不是面向用户的表示字符串。

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,T_0745_0800]}

顺便说一句,这个开始 - 停止时间的命名遵循处理时间跨度的常用方法,称为“半开放”#34;开头是包含,而结尾是独家

转换

我们要做的就是在EnumSet QuarterHours和布尔数组之间来回转换。有关详细信息,请参阅我的问题:Convert between EnumSet and array of boolean values。在这里,我使用简单的for循环方法,但看看更紧凑的Lambda&amp;的其他答案。 Java 8及更高版本中提供的流语法。

以下代码在枚举上调用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数组到下面名为EnumSet的新enumSet2

// 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 );
  

enumSet2:[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