自定义排序的BasicDBObject未按预期排序

时间:2015-10-30 14:54:21

标签: java mongodb sorting

在下面的代码中,我试图按日期自定义按降序列出的BasicDBObject。

打印的输出是:

{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:59"}
{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:20"}
{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:00"}
{ "year" : "2015" , "month" : "01" , "day" : "23" , "time" : "07:30:59"}
{ "year" : "2015" , "month" : "09" , "day" : "26" , "time" : "07:30:59"}

应该是:

{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:59"}
{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:20"}
{ "year" : "2015" , "month" : "12" , "day" : "1" , "time" : "07:30:00"}
{ "year" : "2015" , "month" : "09" , "day" : "26" , "time" : "07:30:59"}
{ "year" : "2015" , "month" : "01" , "day" : "23" , "time" : "07:30:59"}

9月(09)发生在1月(01)之后。

排序比较方法有问题吗?

代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;


public class SortByDate
{

    private void testSort()
    {

        List<DBObject> l = new ArrayList<DBObject>();

        DBObject dbo = new BasicDBObject();
        dbo.put("year", "2015");
        dbo.put("month", "12");
        dbo.put("day", "1");
        dbo.put("time", "07:30:20");
        l.add(dbo);

        dbo = new BasicDBObject();
        dbo.put("year", "2015");
        dbo.put("month", "09");
        dbo.put("day", "26");
        dbo.put("time", "07:30:59");
        l.add(dbo);

        dbo = new BasicDBObject();
        dbo.put("year", "2015");
        dbo.put("month", "12");
        dbo.put("day", "1");
        dbo.put("time", "07:30:59");
        l.add(dbo);

        dbo = new BasicDBObject();
        dbo.put("year", "2015");
        dbo.put("month", "01");
        dbo.put("day", "23");
        dbo.put("time", "07:30:59");
        l.add(dbo);

        dbo = new BasicDBObject();
        dbo.put("year", "2015");
        dbo.put("month", "12");
        dbo.put("day", "1");
        dbo.put("time", "07:30:00");

        l.add(dbo);

        DateTimeFormatter dtf = org.joda.time.format.DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");

        Collections.sort(l, new Comparator<DBObject>()
        {
            @Override
            public int compare(final DBObject o1, final DBObject o2)
            {
                long m1 = dtf.parseMillis((String) o1.get("month")+"/"+(String) o1.get("day")+"/"+(String) o1.get("year")+" "+(String) o1.get("time"));
                long m2 = dtf.parseMillis((String) o2.get("month")+"/"+(String) o2.get("day")+"/"+(String) o2.get("year")+" "+(String) o2.get("time"));

                return (int)m2 - (int)m1;
            }
        });

        for(DBObject d : l){ 
            System.out.println(d.toString()); 
        }

    }

    public static void main(String args[])
    {
        new SortByDate().testSort();
    }

}

1 个答案:

答案 0 :(得分:1)

问题在于:

return (int)m2 - (int)m1;

您将long毫秒转换为int,但值大于Integer.MAX_VALUE,因此发生溢出并且转换返回错误结果(例如,它可能是负数)。 正确的转换可能是:

return (int)(m2 - m1);

但是,如果日期不同很多,仍然可能发生溢出。 正确而安全地执行您需要的方法是使用Long.compare

return Long.compare(m2, m1);