[英]How to Union List<Date> list1 and List<Date> list2 in Java?
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 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 如您所见,在两个日期合并之后的最终列表中,上述输出仍然重复
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:
有两种方式:
SortedSet<ZonedDateTime> union =
new TreeSet<>().addAll( zdtsA ).addAll( zdtsB ) ;
The accepted Answer by GhostCat is correct. GhostCat接受的答案是正确的。 The poorly designed
toString
method masked the fractional second that made each seemingly-duplicate value actually distinct. 设计欠佳的
toString
方法掩盖了小数秒,这使得每个看似重复的值实际上都与众不同。
The old date-time classes such as java.util.Date
and java.util.Calendar
are poorly designed, confusing, and troublesome. 旧的日期时间类(例如
java.util.Date
和java.util.Calendar
设计不良,令人困惑且麻烦。 They are now legacy , supplanted by the java.time classes. 它们现在是遗留的 ,由java.time类取代。
Among the many reasons to replace those old classes is the poor choice of behavior of the toString
method. 替换那些旧类的众多原因之一是
toString
方法的行为选择toString
。 Not only does it dynamically apply a time zone to a value that is actually in UTC, it also masks the fractional second. 它不仅动态地将时区应用于UTC实际值,而且还掩盖了小数秒。 That hiding of the fractional second is your core problem here as you did not realize the values were identical to the second but not identical in the fraction.
在这里,小数秒的隐藏是您的核心问题,因为您没有意识到值与小数秒相同但在小数中并不相同。
The equivalent of java.util.Date
is Instant
. 等效于
java.util.Date
是Instant
。 The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). Instant
类以UTC表示时间轴上的时刻,分辨率为纳秒 (最多十进制的九(9)位数字)。
Fortunately, the implementation of the toString
methods in the java.time classes such as Instant
do not hide the fractional second. 幸运的是,java.time类(例如
Instant
toString
方法的实现不会隐藏小数秒。 By default the fractional second, if any, is displayed in groups of 3 digits as needed for the value. 默认情况下,如果需要,小数秒(如果有的话)以3位数字的组显示。 So you will see zero, three, six, or nine digits of fractional second when generating a String to represent the date-time value.
因此,在生成表示日期时间值的字符串时,您将看到零,三,六或九个小数秒的数字。
Instant
To convert to/from java.time, look to new methods added on the old classes. 要与java.time进行相互转换,请查找在旧类上添加的新方法。
Instant instant = myUtilDate.toInstant();
You can truncate the fractional second if desired. 如果需要,您可以截断小数秒。 You can truncate to any granularity you want, as defined in a
TemporalUnit
such as those implemented in ChronoUnit
such as whole seconds, minutes, hours, etc. 您可以将其截断为所需的任意粒度,如
TemporalUnit
定义的粒度(例如ChronoUnit
实现的ChronoUnit
例如整秒,分钟,小时等。
Instant instant = myUtilDate.toInstant().truncatedTo( ChronoUnit.SECONDS );
If you want to increment by 24-hour increments, call the plus
method on Instant
. 如果要以24小时为增量递增,请在
Instant
上调用plus
方法。
Instant dayLater = instant.plus( 1 , ChronoUnit.DAYS );
ZonedDateTime
If you want to increment by days that respect anomalies such as Daylight Saving Time (DST) rather than simply adding 24-hour increments, apply a time zone ( ZoneId
) to get a ZonedDateTime
object. 如果您想增加尊重异常的天数,例如夏令时(DST),而不是简单地添加24小时增量,请应用时区(
ZoneId
)以获取ZonedDateTime
对象。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
By the way, if you only cared about date and not time-of-day, extract a LocalDate
with a call to toLocalDate
. 顺便说一句,如果您只关心日期而不是时间,请提取对
LocalDate
的调用toLocalDate
。
Increment by days, and collect. 逐日递增,并收集。
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
A TreeSet
is a Set
and so eliminates duplicates. TreeSet
是一个Set
,因此可以消除重复项。 A TreeSet
is also a SortedSet
(see Tutorial ) and so keeps the values sorted, in this case sorted in chronological order. TreeSet
也是SortedSet
(请参见Tutorial ),因此将值保持排序,在这种情况下,将按时间顺序排序。 To union while eliminating duplicates, add all elements of both List
objects to a SortedSet
like TreeSet
. 工会同时消除重复,两者的所有元素添加
List
对象添加到SortedSet
像TreeSet
。
SortedSet<ZonedDateTime> union = new TreeSet<>();
union.addAll( datesA );
union.addAll( datesB );
You can make a List
from the SortedSet
similar to code seen in the Question. 您可以从
SortedSet
创建一个List
,类似于在Question中看到的代码。 The SortedSet iterator traverses the set in ascending element order, so the resulting List
will be in chronological order. SortedSet迭代器按元素升序遍历集合,因此生成的
List
将按时间顺序排列。
List<ZonedDateTime> finalDateList = new ArrayList<>(dateSet);
For more discussion of SortedSet
, see this Question , this , and this . 有关
SortedSet
更多讨论,请参见this , this和this 。
The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as
java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
. 这些类取代了麻烦的旧式旧式日期时间类,例如
java.util.Date
, .Calendar
和java.text.SimpleDateFormat
。
The Joda-Time project, now in maintenance mode , advises migration to java.time. 现在处于维护模式的Joda-Time项目建议迁移到java.time。
To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 。 And search Stack Overflow for many examples and explanations.
并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 .
规格为JSR 310 。
Where to obtain the java.time classes? 在哪里获取java.time类?
The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time.
该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as
Interval
, YearWeek
, YearQuarter
, and more . 您可以在这里找到一些有用的类,比如
Interval
, YearWeek
, YearQuarter
,和更多 。
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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.