Java日期比较器问题

Java日期比较器问题,java,priority-queue,Java,Priority Queue,我在按日期整理比较表时遇到了问题。日期格式应为“dd/MM/yyyy”,因此我从SQL数据库中调用我的信息,然后通过执行以下操作将字符串转换为日期: public void setDeadlineDate(String deadDate) throws ParseException { this.d_date = deadDate; //convert strings to dates formatter = new SimpleDateFor

我在按日期整理比较表时遇到了问题。日期格式应为“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());
}
这两个例子都给我带来了问题,我的priorityqueue deadlinedate没有按照我所希望的正确顺序排列。 在我的数据库中,它们以以下格式保存为varchar“01/12/2012”,即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
    }  

PriorityQueue的文档中说

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


这对我来说非常合适:

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()));
        }
    }

}
当您这样做:
for(jobRequestJr:scheduledJobs){…
时,实际上您使用的是一个隐式的
迭代器
,它不能保证项目将按优先级顺序返回(由您的比较器定义)

如上所述,文件规定:

这个类及其迭代器实现了 集合和迭代器接口 方法迭代器()不能保证遍历 任何特定顺序的优先级队列。如果需要有序遍历, 考虑使用数组。排序(pq.toAlayle())。

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

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

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

while(!scheduledJobs.isEmpty()) {
     ... = scheduledJobs.poll();
     //print, do whatever
}
请记住,这将从队列中删除元素,并且只应用于测试目的,或者根据需要实际处理作业。但这将按实际优先级顺序显示日期

在我看来,
PriorityQueue
应该如何使用似乎有些混乱。我想说,常规用例应该是这样的:

while(!scheduledJobs.isEmpty()) {
     ... = scheduledJobs.poll();
     //print, do whatever
}
  • 向队列中添加元素
  • 定义一个方法来处理队列中的“作业”(每个元素)
  • 当队列不为空时,使用
    poll
    (返回最小值)获取每个元素,并对其执行任何需要执行的操作

哪些值没有正确转换?GetConvertedDadlineDate和compare似乎是正确的。@Javier我得到的输出是按照上面发布的顺序进行的,如果我更改了数据顺序周围的返回值,但只是不知道为什么比较有点不正确,你能说明你是如何声明PriorityQueue的吗?还有,如何声明你得到你的输出了吗?移除头部直到队列为空吗?@pcalcao添加到原始中,我的输出只是我的结果集后的一个打印队列函数,请参见上面的添加作业扫描你只添加打印队列的代码吗?这可能与此有关。如果OP需要优先队列,你的答案会出现分歧完全是这样。感谢您的快速响应,从上面我的代码结构等可以看出,java不是最好的。从我目前的实现来看,在将结果集中的作业添加到队列中之后,我会将其更改为将作业添加到数组中,然后创建队列吗?这取决于您需要什么。如果您只需要处理按顺序,使用PriorityQueue,而不是遍历,只需
轮询
并处理其中的每个对象。PriorityQueue就是这样使用的。目的是将所有内容放入一个队列,然后根据截止日期对队列进行排序,然后在我获得排序到某种执行队列上的日期(还不太远),是的,我会尝试一下,但需要先做一些阅读,这个遍历位?我在我的代码中做了什么?非常感谢你的答案和提示,我的脑袋快要爆炸了,花了我很多时间才让它工作起来。如果我想根据“内存”的大小从队列中删除项目,每天都要学习一些新的东西他们需要,使用.poll方法,然后将它们放入类似FIFO执行堆栈的东西中,并在堆栈从x个作业量达到其内存限制时停止从队列中获取,我将如何实现这样的事情?
08/08/2008
09/09/2009
10/10/2010
11/11/2011
while(!scheduledJobs.isEmpty()) {
     ... = scheduledJobs.poll();
     //print, do whatever
}