[英]Why doesn't the set remove duplicates from the sorted list?
Why doesn't the set remove duplicates from the sorted list ? 为什么集合不能从已排序列表中删除重复项? I have sorted the dates in ascending order which the first printed line shows but the set isn't removing the duplicates.
我已经按照日期的升序对日期进行了排序,第一条打印行显示了该日期,但是该日期并没有删除重复项。 Why is that ?
这是为什么 ? The program prints:
程序打印:
[Mon Apr 20 12:27:47 CDT 2009, Mon Apr 20 12:27:47 CDT 2009, Sun Dec 20 12:27:47 CST 2009] [Sun Dec 20 12:27:47 CST 2009, Mon Apr 20 12:27:47 CDT 2009, Mon Apr 20 12:27:47 CDT 2009] [2009年4月20日星期一,CDT 2009年4月20日星期一,CDT 2009年4月20日,加拿大夏令时间2009年12月20日,星期日12:27:47] [2009年12月20日12月20日,星期日12:27:47 CST,星期一:CDT 2009:27:47,2009年4月20日星期一CDT:27:47]
Shouldn't creating a set remove the duplicate date from the collection ? 创建集不应该从集合中删除重复的日期吗?
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;
}
}
All your dates have different millisecond values, that are not printed in your traces. 您所有的日期都有不同的毫秒值,这些值不会打印在迹线中。 Set the milliseconds to 0.
将毫秒设置为0。
java.util.Date
carries time information with it, you need to zero out the time information then set what you want to be set or exclude the time portion from the comparison inside your custom Comparator
. java.util.Date
带有时间信息, 您需要将时间信息清零,然后设置要设置的内容,或者从自定义Comparator
内部的比较中排除时间部分。
Your custom Comparator
is buggy and redundant. 您的自定义
Comparator
存在错误和冗余。 java.util.Date
already implements Comparable
so you don't need to compare dates again, just called .compare()
on the first Date
instance with the second one as an argument. java.util.Date
已经实现Comparable
因此您无需再次比较日期,只需在第一个Date
实例上调用.compare()
,然后将第二个实例作为参数即可。
Also remember that MONTHS
are ZERO based in Caledar. 还请记住,
MONTHS
是基于Caledar的零。 January == 0
not 1
. 一月==
0
而不是1
。
Never rely on the default toString()
on java.util.Date
, always use a SimpleDateFormatter
instance that displays the entire time stamp down to the milliseconds including a TimeZone
( yyyy-MM-dd'T'HH:mm:ssZ
), preferably ISO-8601 and UTC
TimeZone for deterministic behavior. 永远不要依赖
java.util.Date
上的默认toString()
,始终使用SimpleDateFormatter
实例,该实例显示整个时间戳(以毫秒为单位),包括TimeZone
( yyyy-MM-dd'T'HH:mm:ssZ
),最好ISO-8601和UTC
TimeZone用于确定性行为。
When you use Calendar.getInstance()
it returns "now" to millisecond precision. 当您使用
Calendar.getInstance()
它将“毫秒”返回“毫秒”。 Changing the YMD fields does not clear any of that out, so your two dates are likely off by a millisecond or twenty, which is not included in the default toString()
implementation that you're seeing output from. 更改YMD字段不会清除所有这些内容,因此您的两个日期可能相差一毫秒或二十毫秒,这不包括在您从中看到输出的默认
toString()
实现中。
If you want to set a calendar to a specific time, it is simplest to clear()
it first before starting to set fields. 如果要将日历设置为特定时间,最简单的方法是在开始设置字段之前先将
clear()
。
When you call Calendar.getInstance()
, you get a Calendar
initialized with the current time. 调用
Calendar.getInstance()
,将获得一个使用当前时间初始化的Calendar
。 This includes hours, minutes, seconds, and milliseconds. 这包括小时,分钟,秒和毫秒。 Call
clearTime()
on it to zero them out. 对其调用
clearTime()
将它们归零。
You can use this collection instead 您可以改用此收藏集
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.