有 Java 编程相关的问题?

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

arraylist如何在Java中联合列表<日期>列表1和列表<日期>列表2?

  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;
}}

使用Union Method,我仍然收到重复的日期,您是否有人可以帮助我解决此问题?某个时间答案正确,但有时仍然存在重复的日期请指导我

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 ****************

正如您所看到的,在两个日期合并后,最终列表中仍然存在重复的输出


共 (3) 个答案

  1. # 1 楼答案

    使用设置为筛选器,而不是存储:

        HashSet<String> dateSet = new HashSet<String>();
        return Stream.concat(dateList1.stream(), dateList2.stream())
                .filter(d -> dateSet.add(d.toString()))
                .collect(Collectors.toList());
    
  2. # 2 楼答案

    tl;博士

    SortedSet<ZonedDateTime> union = 
        new TreeSet<>().addAll( zdtsA ).addAll( zdtsB ) ;
    

    细节

    {a1}是正确的。设计拙劣的toString方法掩盖了使每个看似重复的值实际上不同的分数秒

    避免遗留日期时间类

    java.util.Datejava.util.Calendar这样的旧日期时间类设计得很差,容易混淆,也很麻烦。它们现在是legacy,被java.time类取代

    替换这些旧类的众多原因之一是toString方法的行为选择不当。它不仅动态地将时区应用于实际使用UTC的值,还屏蔽了小数秒。隐藏分数秒是你在这里的核心问题,因为你没有意识到这些值与分数秒相同,但在分数中不相同

    爪哇。时间

    ^{}等价的是Instant。{a5}类表示{a6}中时间轴上的一个时刻,分辨率为{a7}(小数点最多九(9)位)

    幸运的是,toString方法在java中的实现。像Instant这样的时间类不隐藏分数秒。默认情况下,分数秒(如果有)按值所需的3位数字分组显示。因此,在生成表示日期时间值的字符串时,您将看到零、三、六或九位小数秒

    Instant

    转换为java或从java转换。时间,看看旧类上添加的新方法

    Instant instant = myUtilDate.toInstant();
    

    截断

    如果需要,您可以truncate小数秒。您可以截断到^{}中定义的任何粒度,如^{}中实现的粒度,如整秒、分钟、小时等

    Instant instant = myUtilDate.toInstant().truncatedTo( ChronoUnit.SECONDS );
    

    如果要以24小时为增量,请调用Instant上的^{}方法

    Instant dayLater = instant.plus( 1 , ChronoUnit.DAYS );
    

    ZonedDateTime

    如果您希望按天递增,而不是简单地添加24小时递增,那么可以应用时区(ZoneId)来获取ZonedDateTime对象

    ZoneId z = ZoneId.of( "America/Montreal" );
    ZonedDateTime zdt = instant.atZone( z );
    

    顺便说一下,如果您只关心日期而不关心一天中的时间,那么通过调用toLocalDate提取一个LocalDate

    按天递增,并收集

    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^{}是A^{},因此消除了重复项。A^{}也是^{}(参见Tutorial),因此保持值的排序,在本例中按时间顺序排序。要在消除重复项的同时进行联合,请将两个^{}对象的所有元素添加到类似SortedSetTreeSet

    SortedSet<ZonedDateTime> union = new TreeSet<>();
    union.addAll( datesA );
    union.addAll( datesB );
    

    您可以从SortedSet中生成一个List,类似于问题中看到的代码。SortedSet迭代器按升序元素顺序遍历集合,因此生成的List将按时间顺序排列

    List<ZonedDateTime> finalDateList = new ArrayList<>(dateSet);
    

    有关SortedSet的更多讨论,请参见this Questionthisthis


    关于java。时间

    java.time框架内置于Java8和更高版本中。这些类取代了麻烦的旧legacy日期时间类,如^{}^{}、&^{}

    现在位于maintenance modeJoda-Time项目建议迁移到java。时间

    要了解更多信息,请参阅Oracle Tutorial。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

    在哪里可以获得java。时间课

    {a38}项目扩展了java。额外上课的时间。这个项目是将来可能添加到java的一个试验场。时间你可以吃鱼翅d这里有一些有用的类,例如^{}^{}^{}more

  3. # 3 楼答案

    你的问题就在这里;正如你所做的:

    dateList1.add(cal.getTime());
    

    当两个日期的打印输出(如上所示)相等时,您假设这两个日期相等。但事实并非如此!你只是忘记了“日期”也包括毫秒。如果您更改格式以包含该信息,您将发现您的日期可能具有相同的小时:分钟:秒。。。但是所有不同的毫秒值

    因此,集合不会看到重复的条目;它只看到所有不同的物体

    所以,为了让你的工会工作,你必须在一个你想忽略的日期内“正常化”那些部分。有两种方式:

    1. 如注释中所述,只需在所有创建的日期对象中按“0”毫秒
    2. 您可以使用树集和自定义比较器;这个比较器可以保证只有毫秒不同的日期显示为相等。但这并不是一个很好的方法,因为你无法控制你的约会中哪一个会“存活”下来