我在按日期排序比较器时遇到问题。日期格式应该是"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());
}
这两个例子都给了我问题,我的优先级队列截止日期没有按照我希望的正确顺序。在我的数据库中,它们被保存为varchar,格式如下"2012年12月1日",因为它不允许我使用它们的日期函数将其保存为英文格式。
它们是我转换字符串然后进行比较的更好方法吗?还是我遗漏了什么?
感谢
编辑:订单日期的输出获取:
- 2011年4月5日
- 2012年12月16日
- 2012年6月18日
- 2013年12月17日
- 2013年12月17日
- 2013年12月16日
- 2013年12月17日
- 2012年8月14日
- 2013年12月19日
我声明优先级队列的位置:
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
}
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接口。中提供的迭代器方法迭代器()不能保证遍历优先级队列。如果您需要有序遍历,考虑使用Arrays.sort(pq.toArray()).
这意味着队列中作业的顺序和迭代器的顺序不一定相同。
如果您只需要列出作业,请使用文档中提到的Arrays.sort
方法。
如果你想确保你的PriorityQueue正常工作,你必须把它作为一个整体,做一些类似的事情:
while(!scheduledJobs.isEmpty()) {
... = scheduledJobs.poll();
//print, do whatever
}
请记住,这将从队列中删除元素,并且只应用于测试目的,或根据需要实际处理作业。但这应该会显示实际优先级顺序中的日期。
在我看来,应该如何使用PriorityQueue
似乎有些混乱。我想说,常规用例应该是这样的:
- 将元素添加到队列
- 定义一个方法来处理队列中的"作业"(每个元素)
- 当队列不为空时,使用
poll
(返回最小值)获取每个元素,并对其执行任何需要执行的操作
方法迭代器()中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray())
http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html
这对我来说非常适用:
public class JobRequest implements Comparable<JobRequest> {
static final DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date convertedDeadlineDate;
Date getConvertedDeadlineDate() {
return convertedDeadlineDate;
}
public JobRequest(String deadDate) {
try {
convertedDeadlineDate = (Date) formatter.parse(deadDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
@Override
public int compareTo(JobRequest j) {
return this.getConvertedDeadlineDate().compareTo(
j.getConvertedDeadlineDate());
}
public static void main(String[] args) {
List<JobRequest> list = new ArrayList<>();
list.add(new JobRequest("10/10/2010"));
list.add(new JobRequest("09/09/2009"));
list.add(new JobRequest("11/11/2011"));
list.add(new JobRequest("08/08/2008"));
Collections.sort(list);
for (JobRequest j : list) {
System.out.println(formatter.format(j.getConvertedDeadlineDate()));
}
}
}
结果是输出:
08/08/2008
09/09/2009
10/10/2010
11/11/2011