有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么集合不从排序列表中删除重复项?

为什么集合不从排序列表中删除重复项?我已经按照第一行显示的升序对日期进行了排序,但是集合没有删除重复项。为什么呢? 程序将打印:
[美国东部时间2009年4月20日星期一12:27:47,美国东部时间2009年4月20日星期一12:27:47,美国中部时间2009年12月20日星期日12:27:47] [美国标准时间2009年12月20日星期日12:27:47,美国东部时间2009年4月20日星期一12:27:47,美国东部时间2009年4月20日星期一12:27:47]

创建集合不应该从集合中删除重复的日期吗

    def void testLoadDoc()
     {
     Date date1 = getCurrentDate(3,20,2009)
     Date date2 = getCurrentDate(11,20,2009)
     Date date3 = getCurrentDate(3,20,2009)


     List<Date> dates = new ArrayList<Date>();
     dates.add(date2);
     dates.add(date1);
     dates.add(date3);

     Collections.sort(dates, new CurrencyDateComparator());
     Set uniqueDates = new HashSet(dates)

     println dates
     println uniqueDates

 }


 private Date getCurrentDate(int month, int day, int year)
 {

     Calendar cal = Calendar.getInstance();
     cal.set(YEAR, year);
     cal.set(MONTH, month);
     cal.set(DAY_OF_MONTH, day);
     return cal.getTime();

 }
}

class CurrencyDateComparator implements Comparator
{
    /* (non-Javadoc)
     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
     */
    public int compare(Object arg0, Object arg1)
    {
        Date p = (Date) arg0;
        Date q = (Date) arg1;

        if (p.before(q))
        {
            return -1;
        }
        else if (p.after(q))
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }

    public boolean equals(Object o)
    {
        if (o instanceof CurrencyDateComparator)
        {
            CurrencyDateComparator c = (CurrencyDateComparator) o;

            return this.equals(o);
        }
        else
        {
            return false;
        }
    }

共 (5) 个答案

  1. # 1 楼答案

    所有日期都有不同的毫秒值,这些值不会打印在跟踪中。将毫秒设置为0

  2. # 2 楼答案

    当您调用Calendar.getInstance()时,您会得到一个用当前时间初始化的Calendar。这包括小时、分钟、秒和毫秒。调用^{}将其归零

  3. # 3 楼答案

    当您使用Calendar.getInstance()时,它将“now”返回毫秒精度。更改Y-M-D字段并不能清除其中的任何一个,因此您的两个日期可能相差一毫秒或二十毫秒,这不包括在您看到输出的默认toString()实现中

    如果要将日历设置为特定时间,最简单的方法是在开始设置字段之前clear()先设置日历

  4. # 4 楼答案

    您可以改为使用此集合

    Set<Date> dates = new TreeSet<Date>(CurrencyDateComparator.INSTANCE);
    dates.add(date2);
    dates.add(date1);
    dates.add(date3);
    
    enum CurrencyDateComparator implements Comparator<Date> {
        INSTANCE;
    
        static final long MILLI_PER_DAY = 86400000L;
        public int compare(Date d1, Date d2) {
            // older versions of Java can use Double.compare()
            return Long.compare(d1.getTime() / MILLIS_PER_DAY, d2.getTime() / MILLIS_PER_DAY);
        }
    }
    
  5. # 5 楼答案

    首先

    java.util.Date携带时间信息,you need to zero out the time information然后设置要设置的内容,或者从自定义Comparator内的比较中排除时间部分

    第二

    您的自定义Comparator有缺陷且冗余java.util.Date已经实现了Comparable,因此您不需要再次比较日期,只需在第一个Date实例上调用.compare(),并将第二个实例作为参数

    第三

    还要记住MONTHS在Caledar中是以零为基础的。一月=={}不是{}

    第四

    永远不要依赖于java.util.Date上的默认toString(),始终使用一个SimpleDateFormatter实例来显示整个时间戳,直到毫秒,包括一个TimeZoneyyyy-MM-dd'T'HH:mm:ssZ),最好是ISO-8601和UTC时区,用于确定性行为