我在按日期整理我的比较器时遇到问题。日期格式应为“ 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获取每个元素(返回最小的元素),然后执行您需要做的任何事情。

10-07 19:15
查看更多