定时器
来源:互联网 发布:杭州金融投资集团 知乎 编辑:程序博客网 时间: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;
其中的第三点很容易遗漏,这里要注意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的键和值都不能为空。
迭代时注意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()); } } }}