我有一个定义的类来管理游戏室。当用户创建新房间时,我会生成一个具有唯一房间号的新房间,并将其添加到哈希集中。
现在,我希望从hashset中删除Room对象并回收Room对象以获取perfarmance问题,比如24小时,或者放弃的Room对象将花费我的大部分内存
我怎样才能做到这一点?此外,任何改善表现的建议都将受到高度赞赏。
我的课程如下:
public class RoomService {
private RoomService(){
super();
}
private HashSet<Room> roomSet =new HashSet<Room>();
private static RoomService instance =new RoomService();
public static RoomService getServiceInstance(){
return instance;
}
private static Integer generateRandom(int length) {
Random random = new Random();
char[] digits = new char[length];
digits[0] = (char) (random.nextInt(9) + '1');
for (int i = 1; i < length; i++) {
digits[i] = (char) (random.nextInt(10) + '0');
}
return Integer.decode(new String(digits));
}
/**
* Generate new Room with an unique Room number
* @return
*/
public Room newRoom(){
Room newRoom;
do{
newRoom =new Room(generateRandom(4));
}
while(!roomSet.add(newRoom));
return newRoom;
}}
public class Room {
private Integer roomNum;
private Date createTime=new Date();
private String creatorId;
/*
* constructor
*/
public Room(Integer roomNum) {
super();
this.roomNum = roomNum;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((roomNum == null) ? 0 : roomNum.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Room other = (Room) obj;
if (roomNum == null) {
if (other.roomNum != null)
return false;
} else if (!roomNum.equals(other.roomNum))
return false;
return true;
}
//getter and setter
//
//
public String getCreatorId() {
return creatorId;
}
public void setcreatorId(String creatorId) {
this.creatorId = creatorId;
}
public Integer getRoomNum() {
return roomNum;
}
public Date getCreateTime() {
return createTime;
}
}
答案 0 :(得分:1)
您可以使用Timer自行完成此操作。每次有人创建新房间时,您都会创建一个新的TimerTask实例,该实例将再次删除该ID,并使用public void schedule(TimerTask task, Date time)
安排执行该任务。它可能看起来像这样:
private final Timer timer; // Initialised somewhere
public Integer newRoomNum() {
Integer newRoomNum = ... // Create id
Date date = ... // Create date when the id should be deleted again
timer.schedule(new DeleteKeyTask(newRoomNum), date);
return newRoomNum;
}
DeleteKeyTask
是TimerTask
的自定义子类,删除给定的ID。
private class DeleteKeyTask extends TimerTask {
private final Integer id;
public DeleteKeyTask(Integer id) {
this.id = id;
}
@Override
public void run() {
// remove id
}
您可以使用不同的方法节省空间:
您可以将日期与整数键一起存储,而不是每个键都有一个任务。例如,您可以使用HashMap<Integer, Date>
(或存储毫秒而不是日期)。地图的键形成您之前的设置。这些值表示密钥插入或过期的时间。
然后,您可以安排计时器删除下一个过期密钥,此时您将查找下一个过期密钥并计划删除该密钥等。这将花费您O(n)
时间来计算下一个过期密钥。您的任务运行方法看起来像
public void run() {
map.remove(id);
Integer next = ... // Find next expiring key
timer.schedule(new DeleteKeyTask(next), map.get(next));
}
您需要调整创建方法:
public Integer create() { // Previously newRoomNum()
Integer newRoomNum = ... // Create id
Date date = ... // Create date when the id should be deleted again
if(map.isEmpty()) // Only schedule when empty
timer.schedule(new DeleteKeyTask(newRoomNum), date);
map.put(newRoomNum, date);
return newRoomNum;
}
这样您只需要存储每个整数的日期。如果在计算下一个时O(n)
开销太大,您可以通过使用更多空间来加快速度:使用Queue并插入新密钥。该队列将允许您检索下一个过期密钥,从而查找下一个过期密钥O(1)
。