0

我在按日期整理比较器时遇到问题。日期格式应为“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());
}

这两个例子都给了我问题,我的优先队列截止日期没有按照我想要的正确顺序排列。在我的数据库中,它们以 2012 年 12 月 1 日以下格式“01/12/2012”保存为 varchar,因为它不允许我使用他们的日期函数将其保存为英文格式。

他们是我转换字符串然后比较的更好方法还是我错过了什么?

谢谢

编辑:获取订购日期的输出:

  • 2011 年 5 月 4 日
  • 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
    }  

scheduleJobs.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());

        }
    }
4

3 回答 3

2

当你这样做时:for (JobRequest jr : scheduledJobs) { ...你实际上是在使用一个 implicit Iterator,它不能保证这些项目将按优先级顺序返回(由你的比较器定义)。

如上所述,文档指出:

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。方法 iterator() 中提供的 Iterator 不能保证以任何特定顺序遍历优先级队列的元素。如果您需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())。

这意味着队列中作业的顺序和迭代器的顺序不一定相同。

如果您只需要列出工作,请使用Arrays.sort文档中提到的方法。

如果您想确保您的 PriorityQueue 正常工作,您必须将它作为一个整体使用,执行以下操作:

while(!scheduledJobs.isEmpty()) {
     ... = scheduledJobs.poll();
     //print, do whatever
}

请记住,这会从队列中删除元素,并且只能用于测试目的,或者根据需要实际处理作业。但这应该以实际优先顺序向您显示日期。

在我看来,PriorityQueue应该如何使用存在一些混淆。我会说常规用例类似于:

  • 将元素添加到队列
  • 定义一个方法来处理队列中的“作业”(每个元素)
  • 当队列不为空时,使用poll(返回最小的)获取每个元素,然后做任何你需要做的事情。
于 2013-02-18T14:39:30.040 回答
0

PriorityQueue 的文档说

方法 iterator() 中提供的 Iterator 不能保证以任何特定顺序遍历优先级队列的元素。如果您需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())

. http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html

于 2013-02-18T14:26:44.367 回答
0

这对我来说非常有效:

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
于 2013-02-18T14:33:02.990 回答