定时器

来源:互联网 发布:杭州金融投资集团 知乎 编辑:程序博客网 时间:2024/06/05 16:54

描述: 设计一个定时器管理系统,可以动态启动、停止定时器,并能根据已逝去的时长自动调整剩余的时长以及停止定时器
运行时间限制: 1 Sec
内存限制: 无限制

  • 启动定时器:starttimer:ID,time
    举例: starttimer:1,1000
    启动一个定时器,其ID为1,定时时长time为1000ms
    注:定时器ID用例保证非负整数;定时时长一定为正整数

  • 停止定时器:stoptimer:ID
    举例:
    stoptimer:1
    停止一个ID为1的定时器
    注:定时器ID用例保证非负整数;如果停止的定时器ID不存在,则忽略

  • 逝去时长:elapse:time
    举例:
    elapse:1000
    时间逝去1000ms
    注:用例保证时长一定为正整数

  • 输入结束end

  • 输出:
    按启动顺序输出还没有停止的定时器,如下ID为1的定时器还有1000ms才结束
    timer:1,1000
    如果所有定时器都停止了,输出none

样例输入:
starttimer:1,1000
starttimer:2,2000
elapse:1000
end
样例输出:
timer:2,1000

这道题最终并没有AC,仔细阅读了所有要求,提取得到的关键信息有:

  • 输入有四种,分别对应处理;
  • 输入为stoptimer时,注意定时器不存在的情况;
  • 输入结束时,要按照启动顺序来依次输出没有停止的定时器,没有时输出none;

    1. 其中的第三点很容易遗漏,这里要注意HashMap、TreeMap、LinkedListMap、HashTable四者的使用区别:

      本节来自于HashMap、HashTable、LinkedHashMap和TreeMap用法和区别

      Map用于存储键值对,根据键得到值,因此不允许键重复,值可以重复。以上四种都是Java为数据结构中的映射定义了一个接口java.util.Map的四个实现类。

      • HashMap是一个最常用的Map,它根据键的hashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap**最多只允许一条记录的键为null**,不允许多条记录的值为null。HashMap**不支持线程的同步**,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用Collections.synchronizedMap(HashMap map)方法使HashMap具有同步的能力。
      • Hashtable与HashMap类似,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,然而,这也导致了Hashtable在写入时会比较慢
      • LinkedHashMap**保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的。在遍历的时候会比HashMap慢**。有HashMap的全部特性。
      • TreeMap能够把它保存的记录根据键排序默认是按升序排序,也可以指定排序的比较器。当用Iteraor遍历TreeMap时,得到的记录是排过序的。TreeMap的键和值都不能为空
    2. 迭代时注意map的遍历方法及遍历时报错:
      map的遍历方法

  //第一种:普遍使用,二次取值  System.out.println("通过Map.keySet遍历key和value:");  for (String key : map.keySet()) {   System.out.println("key= "+ key + " and value= " + map.get(key));  }  //第二种  System.out.println("通过Map.entrySet使用iterator遍历key和value:");  Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();  while (it.hasNext()) {   Map.Entry<String, String> entry = it.next();   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  }  //第三种:推荐,尤其是容量大时  System.out.println("通过Map.entrySet遍历key和value");  for (Map.Entry<String, String> entry : map.entrySet()) {   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  }  //第四种  System.out.println("通过Map.values()遍历所有的value,但不能遍历key");  for (String v : map.values()) {   System.out.println("value= " + v);  }

在使用iterator.hasNext()操作迭代器的时候,如果此时迭代的对象发生改变,比如插入了新数据,或者有数据被删除。
则使用会报以下异常:

Java.util.ConcurrentModificationException       at java.util.HashMap\$HashIterator.nextEntry(HashMap.java:793)       at java.util.HashMap\$KeyIterator.next(HashMap.java:828)

解决办法:java.util.ConcurrentModificationException 解决办法


3.  其他OJ的一些编程建议:if else括号,map遍历在entrySet上使用iterator比keySet再Map.get更高效....
import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Map;import java.util.Scanner;public class Main {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        Scanner sc=new Scanner(System.in);        Map<String,Integer> map= new LinkedHashMap<String,Integer>();        while(sc.hasNext()){            String str=sc.nextLine();            if(str.equals("end")) break;            String[] temp=str.split(":");            if(temp[0].equals("starttimer")){                String[] info=temp[1].split(",");                String id=info[0];                int time=Integer.parseInt(info[1]);                    map.put(id, time);            }            else if(temp[0].equals("elapse")){                int time=Integer.parseInt(temp[1]);                if(time>0){                    Iterator<Map.Entry<String,Integer>> it= map.entrySet().iterator();                    while(it.hasNext()){                        Map.Entry<String, Integer> entry = it.next();                        String key=entry.getKey();                        int left=entry.getValue()-time;                         if(left<=0){                                  it.remove();                              }                               else{                                  map.remove(key);                                  map.put(key, left);                              }                      }                }            }            else if(temp[0].equals("stoptimer")){                if(map.containsKey(temp[1])){                    map.remove(temp[1]);                }            }        }        int len=map.size();        if(len==0){            System.out.println("none");        }        else{            for(Map.Entry<String, Integer> entry : map.entrySet()){                System.out.println("timer:"+entry.getKey()+","+entry.getValue());            }        }    }}
0 0