我在按日期整理我的比较器时遇到问题。日期格式应为“ dd / MM / yyyy”,因此我从SQL数据库中调用信息,然后通过执行以下操作将字符串转换为日期:
public void setDeadlineDate(String deadDate) throws ParseException {
this.d_date = deadDate;
//convert strings to dates
formatter = new SimpleDateFormat("dd/MM/yyyy");
convertedDeadlineDate = (Date)formatter.parse(deadDate);
}
然后,在下面创建一个get方法来调用我的比较器。我不得不举一些例子,但是关于奇数日期不合适和比较不正确始终存在差异。
范例1:
@Override
public int compare(JobRequest j1, JobRequest j2) {
if (j1.getConvertedDeadlineDate().before(j2.getConvertedDeadlineDate())) {
return -1;
} else if (j1.getConvertedDeadlineDate().after(j2.getConvertedDeadlineDate())) {
return 1;
}
else {
return 0;
}
}
范例2:
public int compare(JobRequest j1, JobRequest j2){
return j1.getConvertedDeadlineDate().compareTo(j2.getConvertedDeadlineDate());
}
这两个例子都给我带来了问题,我的优先队列截止日期也没有按照我想要的顺序排列。
在我的数据库中,它们以以下格式“ 01/12/2012”(2012年12月1日)另存为varchar,因为这不会让我使用其date函数将其转换为英语格式。
他们是我转换字符串然后进行比较的更好方法还是我错过了什么?
谢谢
编辑:
获取订购日期的输出:
2011/05/04
2012年12月16日
2012年6月18日
2013年12月17日
2013年12月17日
2013年12月16日
2013年12月17日
2012年8月14日
2013年12月19日
我在其中声明PriortyQueue的地方:
private Comparator<JobRequest> comparator = new JobQueueComparator(); //calls my comparator
private PriorityQueue< JobRequest> scheduledJobs = new PriorityQueue<JobRequest>(100, comparator);
public void addJob(JobRequest job) {
// now add job to priority queue
scheduledJobs.add(job); // add jobs from the resultset into queue
}
cheduleJobs.add(job)只是从结果集中填充队列,并一直添加到队列中,直到读取数据库中的所有字段为止,请参见下文
public void populateQueueFromDB() {
// create priority queue
try {
String url = "jdbc:mysql://localhost:3306/project";
Connection conn = DriverManager.getConnection(url, "root", "nbuser");
PreparedStatement stmt = conn.prepareStatement("SELECT user_id,s_date,e_date,d_date,department,projectname,projectapplication,priority,cores,disk_space,analysis FROM booking");
ResultSet rs;
rs = stmt.executeQuery();
//List<JobRequest> jobList = new ArrayList<JobRequest>();
while (rs.next()) {
JobRequest job = new JobRequest();
User user = new User();
user.setUserID(rs.getString("user_id"));
job.setUserID(user.getUserID()); // changes the /user id to the job.setuser id so can call for my queue print.
job.setStartDate(rs.getString("s_date"));
job.setEndDate(rs.getString("e_date"));
job.setDeadlineDate(rs.getString("d_date"));
job.setDepartment(rs.getString("department"));
job.setProjectName(rs.getString("projectname"));
job.setProjectApplication(rs.getString("projectapplication"));
job.setPriority(rs.getInt("priority"));
job.setCores(rs.getInt("cores"));
job.setDiskSpace(rs.getInt("disk_space"));
job.setAnalysis(rs.getString("analysis"));
schedulerPriorityQueue.addJob( job );
}
schedulerPriorityQueue.printQueue();
conn.close();
} catch (Exception e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}
}
打印队列:
public void printQueue() {
for (JobRequest jr : scheduledJobs) {
System.out.print(jr.getUserID() + "-->");
System.out.print(jr.getStartDate() + "--START-->");
System.out.print(jr.getEndDate() + "---END-->");
System.out.print(jr.getDeadDate() + "--DROP-->");
System.out.print(jr.getDepartment() + "-->");
System.out.print(jr.getProjectName() + "-->");
System.out.print(jr.getProjectApplication() + "-->");
System.out.print(jr.getPriority() + "--PRIORITY-->");
System.out.print(jr.getCores() + "-->");
System.out.print(jr.getDiskSpace() + "-->");
System.out.println(jr.getAnaylsis());
}
}
最佳答案
当您执行以下操作时:for (JobRequest jr : scheduledJobs) { ...
实际上是在使用隐式的Iterator
,这不能保证将按优先级顺序(由比较器定义)返回项目。
如上文所述,文档指出:
此类及其迭代器实现以下所有可选方法
Collection和Iterator接口。提供的Iterator
方法iterator()不能保证遍历
以任何特定顺序的优先级队列。如果您需要顺序遍历,
考虑使用Arrays.sort(pq.toArray())。
这意味着队列中作业的顺序和迭代器的顺序不一定相同。
如果只需要列出作业,请使用文档中提到的Arrays.sort
方法。
如果要确保PriorityQueue正常工作,则必须将它作为一个使用,并执行以下操作:
while(!scheduledJobs.isEmpty()) {
... = scheduledJobs.poll();
//print, do whatever
}
请记住,这将从队列中删除元素,并且仅应用于测试目的或根据需要实际处理作业。但这应该以实际的优先顺序显示日期。
在我看来,
PriorityQueue
的使用方式有些混乱。我会说常规用例将是这样的:将元素添加到队列
在队列中定义一种方法来处理“工作”(每个元素)
当队列不为空时,使用
poll
获取每个元素(返回最小的元素),然后执行您需要做的任何事情。