我尝试打印的输出没有打印,试图用HashMap制作基于文本的闹钟

时间:2014-06-28 18:17:15

标签: java hashmap

我正在尝试将当前时间与HashMap中的值进行比较,以打印通知消息(如警报)。但是,当当前时间达到等于HashMap中的值的时间时,它不会打印。这是因为containsValue方法没有足够的时间来迭代HashMap或其他原因吗?这是我的相关代码:

private SimpleDateFormat timeFormat = new SimpleDateFormat("kk:mm:ss");

@Override
    public void run() {
        while (true) {
            String currentTime = getCurrentTime();
                if (callLog.containsValue(currentTime)) {
                    System.out.println("it works!");
                }
    }

public String getCurrentTime() {
        Date time = Calendar.getInstance().getTime();
        String currentTIme = timeFormat.format(time);
        return currentTIme;
    }

编辑:好的,我通过一些调整找出了问题所在。如果我在我设置闹钟的确切时刻运行程序,我的if检查是否有效。如果我等待闹钟响起(例如程序运行后2分钟),则不会发送消息。修改后的代码:

private HashMap<Integer, String> callLog;
        private SimpleDateFormat timeFormat = new SimpleDateFormat("kk:mm:ss");
        private String wakeUpMessage = "This is your automatic wake up call for room number: ";
        private String nextCall;
        private Thread thread;

        public HotelSystem() {
            callLog = new LinkedHashMap<Integer, String>();
            this.thread = new Thread(this);
            this.thread.start();
            setAlarmTime(4, "20:45:00");
        }

        @Override
        public void run() {
            while (true) {
                if (callLog.containsValue(getCurrentTime())) {
                    System.out.println(getCurrentTime());
                    sendAlarmCall(4);
                }
            }
        }

        // sends a generic alarm call message followed by the room number
        public void sendAlarmCall(int roomNumber) {
            System.out.println(wakeUpMessage + roomNumber);
        }

public String getCurrentTime() {
        Date time = Calendar.getInstance().getTime();
        String currentTIme = timeFormat.format(time);
        return currentTIme;
    }

    public void setAlarmTime(int roomNumber, String time) {
        Date alarmDate;
        try {
            alarmDate = timeFormat.parse(time);
            String alarmTime = timeFormat.format(alarmDate);
            callLog.put(roomNumber, alarmTime);
            System.out.println("You entered room number: " + roomNumber + " and wake up time of: " + alarmTime);
        } catch (ParseException e) {
            System.out.println("Please ensure you seperate the time with colons eg 07:30:00.");
        }

    }

编辑2:好的,现在真的很奇怪。它适用于我放入的所有内容,除非秒等于00.我不知道它为什么会这样做。

2 个答案:

答案 0 :(得分:2)

我很确定它从来没有&#34;时间等于HashMap中的值#34;正如你所说。如果您的标准输出正在运行(System.out要写入的控制台),则if条件永远不会被评估为true。

方法containsValue肯定有足够的时间进行评估。除非你打断整个线程,否则不可能在其评估过程中中断某个方法(至少在你的情况下),除非你打断整个线程。

寻找可能的解决方案:

a)在调试模式下,检查hashmap中的字符串值类型以及currentTime字符串的外观。可能存在格式问题。从您的代码中,无法分辨callLog包含的值。

b)不要将时间与字符串进行比较。我知道你需要在几秒钟内达到分辨率(毫秒或纳米可能导致问题&#34;达到等于时间&#34;),但是通过将Date转换为字符串这样做是资源匮乏和缓慢的方式。你实际可以做的是创建自己的类,例如ScheduleTime包含很少的原始属性(小时,分钟,秒)并覆盖hashCode()和equals()方法。有很多关于如何正确执行此操作的教程,非常简单。

c) run()方法不经常调用。如果您希望在几秒钟内获得时间分辨率,请确保每秒触发此方法。

还考虑使用Thread.sleep()而不是一遍又一遍地创建和销毁线程。但是这样,你必须引用你的hashmap作为线程对象的属性。但是HashMap不是ThreadSafe,为了线程安全,有ConcurrentHashMap。但这只是一个推荐。

答案 1 :(得分:1)

如果您的程序一直在运行,使用ScheduledThreadPoolExecutor或只是java.util.Timer可以帮助您。它们允许存储在没有CPU循环的情况下调用的定时器。

如果您想使用闹钟时间自己制作一个TreeMap,那么整数键可能是一个好的开始。