public class ArrayOfArrayList {
public static void main(String[] args) {
List<Date> dateList1 = new ArrayList<Date>();
List<Date> dateList2 = new ArrayList<Date>();
Calendar cal = new GregorianCalendar();
for(int i = 0; i < 5; i++) {
Date d1 = new Date();
cal.setTime(d1);
cal.add(Calendar.DATE, i);
dateList1.add(cal.getTime());
}
System.out.println(" *************** Date List 1st ****************");
for(Date date1 : dateList1) {
System.out.println("1stList"+date1);
}
System.out.println(" *************** Date List 1st ****************");
for(int i = 2; i < 8; i++) {
Date d2 = new Date();
cal.setTime(d2);
cal.add(Calendar.DATE, i);
dateList2.add(cal.getTime());
}
System.out.println(" *************** Date List 2nd ****************");
for(Date date2 : dateList2) {
System.out.println("2ndList"+date2);
}
System.out.println(" *************** Date List 2nd ****************");
System.out.println(" *********** Start Union Dates ************");
List<Date> finalList = union(dateList1,dateList2);
Collections.sort(finalList);
System.out.println("\n ********* After Union Dates ***********");
for(Date fDate : finalList) {
System.out.println(fDate);
}
System.out.println("\n ********* After Union Dates **********");
}
private static List<Date> union(List<Date> dateList1, List<Date> dateList2) {
HashSet<Date> dateSet = new HashSet<Date>();
dateSet.addAll(dateList1);
dateSet.addAll(dateList2);
List<Date> finalDateList = new ArrayList<Date>(dateSet);
return finalDateList;
}}
with Union Method still i am getting Duplicate Dates could you anyone help me to fix this issue some time answer comes correct but sometime duplicate still present please guide me
O/P
*************** Date List 1st ****************
1stListFri Oct 21 00:38:53 IST 2016
1stListSat Oct 22 00:38:53 IST 2016
1stListSun Oct 23 00:38:53 IST 2016
1stListMon Oct 24 00:38:53 IST 2016
1stListTue Oct 25 00:38:53 IST 2016
*************** Date List 1st ****************
*************** Date List 2nd ****************
2ndListSun Oct 23 00:38:53 IST 2016
2ndListMon Oct 24 00:38:53 IST 2016
2ndListTue Oct 25 00:38:53 IST 2016
2ndListWed Oct 26 00:38:53 IST 2016
2ndListThu Oct 27 00:38:53 IST 2016
2ndListFri Oct 28 00:38:53 IST 2016
*************** Date List 2nd ****************
*************** Start Union Dates ****************
*************** After Union Dates ****************
Fri Oct 21 00:38:53 IST 2016
Sat Oct 22 00:38:53 IST 2016
Sun Oct 23 00:38:53 IST 2016
Sun Oct 23 00:38:53 IST 2016
Mon Oct 24 00:38:53 IST 2016
Mon Oct 24 00:38:53 IST 2016
Tue Oct 25 00:38:53 IST 2016
Tue Oct 25 00:38:53 IST 2016
Wed Oct 26 00:38:53 IST 2016
Thu Oct 27 00:38:53 IST 2016
Fri Oct 28 00:38:53 IST 2016
*************** After Union Dates ****************
As you can see the Above Outputs still duplicate is present in the final list after Union of two dates
答案 0 :(得分:5)
Your problem is here; as you do:
dateList1.add(cal.getTime());
You assume that two dates are equal when their printout (like above) is equal. But that is not true! You simply forgot that "dates" include milli seconds, too. If you change your formatting to include that information, you will find that your dates might have same hours:minutes:seconds ... but all different milli second values!
Thus the Set does not see duplicated entries; it just sees all different objects!
So, in order to make your union work, you have to "normalize" those parts within a Date that you want to ignore. Two ways there:
答案 1 :(得分:2)
SortedSet<ZonedDateTime> union =
new TreeSet<>().addAll( zdtsA ).addAll( zdtsB ) ;
accepted Answer by GhostCat是正确的。设计糟糕的toString
方法掩盖了小数秒,使得每个看似重复的值实际上都是不同的。
java.util.Date
和java.util.Calendar
等旧的日期时间类设计不当,令人困惑且麻烦。它们现在是legacy,取代了java.time类。
替换这些旧类的众多原因之一是toString
方法的行为选择不当。它不仅动态地将时区应用于实际为UTC的值,还会屏蔽小数秒。隐藏小数秒是你的核心问题,因为你没有意识到值与第二个相同但在分数中不相同。
等同于java.util.Date
的是Instant
。 Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
幸运的是,java.time类中的toString
方法的实现,例如Instant
,隐藏了小数秒。默认情况下,小数秒(如果有)将根据值的需要以3位数组显示。因此,当生成表示日期时间值的字符串时,您将看到零,三,六或九位小数秒。
Instant
要转换为/从java.time,请查看旧类上添加的新方法。
Instant instant = myUtilDate.toInstant();
如果需要,您可以truncate小数秒。您可以截断为TemporalUnit
中定义的任何粒度,例如ChronoUnit
中实现的粒度,例如整秒,分钟,小时等。
Instant instant = myUtilDate.toInstant().truncatedTo( ChronoUnit.SECONDS );
如果您想以24小时为增量递增,请拨打Instant
上的plus
方法。
Instant dayLater = instant.plus( 1 , ChronoUnit.DAYS );
ZonedDateTime
如果您希望按照夏令时(DST)等异常增加天数而不是简单地添加24小时增量,请应用时区(ZoneId
)来获取ZonedDateTime
个对象
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
顺便说一句,如果您只关心日期而不关注时间,请拨打LocalDate
并toLocalDate
。
按天增加,并收集。
int count = 5 ;
List<ZonedDateTime> datesA = new ArraySet<>( count );
for( int i = 1 , i <= count , i++ ) {
datesA.add( zdt );
// Prepare for next loop.
zdt = zdt.plusDays( 1 );
}
SortedSet
TreeSet
是Set
,因此可以消除重复项。 TreeSet
也是SortedSet
(请参阅Tutorial),因此保持值的排序,在这种情况下按时间顺序排序。要在删除重复项时进行联合,请将List
个对象的所有元素添加到SortedSet
TreeSet
。
SortedSet<ZonedDateTime> union = new TreeSet<>();
union.addAll( datesA );
union.addAll( datesB );
您可以从问题中看到的代码List
中创建SortedSet
。 SortedSet迭代器以升序元素顺序遍历集合,因此生成的List
将按时间顺序排列。
List<ZonedDateTime> finalDateList = new ArrayList<>(dateSet);
有关SortedSet
的更多讨论,请参阅this Question,this和this。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,.Calendar
和&amp; java.text.SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:-1)
Use set as filter, not as storage:
HashSet<String> dateSet = new HashSet<String>();
return Stream.concat(dateList1.stream(), dateList2.stream())
.filter(d -> dateSet.add(d.toString()))
.collect(Collectors.toList());