优先级队列-Java日期比较器问题



我在按日期排序比较器时遇到问题。日期格式应该是"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(返回最小值)获取每个元素,并对其执行任何需要执行的操作
PriorityQueue的文档表明

方法迭代器()中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用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

最新更新