【问题标题】:how to check if an object with a certain date already exists in a ArrayList如何检查具有特定日期的对象是否已存在于ArrayList中
【发布时间】:2021-02-16 20:01:54
【问题描述】:

我有点卡在我正在做的一个项目中。所以我正在编写一个 Hotel 类(父)和一个 Reservation 类(子)。

在我的预订课程中,我正在创建要在酒店进行的新预订。我的预订构造函数采用以下参数Reservation(String name, String Email, int phonenum, LocalDate fromDate, LocalDate toDate).

但是,我现在想在创建新预订时检查是否已经进行了预订。 我所有的对象都保存在ArrayList 中,但考虑到我构建日期的方式,我不太确定该怎么做。任何精确的指针将不胜感激!

编辑:

            public List<Reservation> addBooking(int addBooking){  // argument doesnt do anything at the moment, havent decided what I should opt for. 
                if (addBooking <= 0 || addBooking > 10)
                    throw new IllegalArgumentException("Number of reservations must be higher than 0 and can't exceed 10!");
                
                
                else
                    reservations.add(new Reservation("Alex Test", "abrdwa@gmail.com",99323223,LocalDate.now().plusDays(10), LocalDate.now().plusDays(15)));
                    reservations.add(new Reservation("Criss Test2", "acdef@gmail.com",47825433,LocalDate.now().plusDays(10), LocalDate.now().plusDays(15)));
                    reservations.add(new Reservation("Frank Test3", "abcde@gmail.com",41722210,LocalDate.now().plusDays(10), LocalDate.now().plusDays(15)));
                    reservations.add(new Reservation("Elea Test4", "abcd@gmail.com",99321312,LocalDate.now().plusDays(10), LocalDate.now().plusDays(15)));
                    reservations.add(new Reservation("Monica Test5", "abc@hotmail.com",99922223,LocalDate.now().plusDays(10), LocalDate.now().plusDays(15)));
    
    
            
            return reservations;
    
            }

【问题讨论】:

  • 请将代码粘贴到编辑器本身,而不是放置图像链接。这样其他人可以更快地阅读您的代码。您可以将其标记为 Java 代码,它将具有正确的语法着色。
  • 看起来你也没有解释int addBooking 参数的用途,并且它没有在任何地方使用。
  • 是的,我知道 int addBooking。目前它什么也没做。一旦我决定了我想要论证做什么,我会尽快解决这个问题。
  • 是用equals 方法拟合你的Reservation 类吗?

标签: java object arraylist compare localdate


【解决方案1】:

这是我将采用的高级方法。

  1. Hotel 类包含 Reservations 的 ArrayList 但你不要直接修改它..
  2. Hotel 类有一个 boolean addReservation(Reservation) 方法,该方法采用 Reservation 并将其添加到数组中并返回 true,如果它“已经生成”则返回 false。
  3. 需要更清楚地定义术语“已经完成”。您的意思是已经进行了相同的预订吗?或者您的意思是您要检查它是否与其他预订不冲突?如果是后者,那么您需要遍历现有预订并比较每个预订的日期开始和结束时间。

【讨论】:

  • 是的,已经制作,因此存在冲突。我的问题是,当我的日期按原样创建时,我看不到如何比较这些日期。非常感谢您的响应和时间!
  • 你让他们影响的方式如何?你不能只使用LocalDate.compareTo()isBeforeisAfter 等吗?见howtodoinjava.com/java/date-time/compare-localdates
【解决方案2】:

首先你要考虑什么是相同的保留。所有字段都相同,包括确切的日期?还是重叠日期?还是只是姓名和电子邮件?根据此覆盖 Reservation 中的 equal 方法。 比你可以添加一个检查:

if(reservations.contains(newReservationAttempt){
  //do whatever you want, return a boolean inside a method or
  throw new ReservationAlreadyExistException()      
}

另一种可能性是检查 Java Streams 的标准和任何匹配项。

【讨论】:

  • 感谢您的及时回复。抱歉不清楚 - 我只想检查 to 和 from-date 是否已经存在,您可以忽略其他所有内容。因此,如果已经在 20.02.2021 - 25.02.2021 进行了预订,并且您尝试在完全相同的时间段进行预订,则应该会引发错误。从 21.02.2021 - 25.02.2021 进行预订应该没问题。
【解决方案3】:

LocalDateRange

我建议您将ThreeTen-Extra 库添加到您的项目中。该库带来了添加到 Java 8 及更高版本中内置的 java.time 功能的类。事实上,这个库和 java.time 都是由同一个人 Stephen Colebourne 领导的。

特别是,ThreeTen-Extra 提供了LocalDateRange 类。此类将时间跨度表示为一对LocalDate 对象。该类提供了方便的比较方法,例如abutsoverlaps等。

所以你的Reservation 类应该包含一个成员字段LocalDateRange 用于开始和结束日期。

如果使用 Java 16 或更高版本,我们可以将您的 Reservation 类更简单地编写为 record。在记录中,编译器隐式创建构造函数、getter、equals & hashCodetoString

package work.basil.example.hotel;

import org.threeten.extra.LocalDateRange;

public record Reservation(String customerName , String customerEmail , int id , LocalDateRange arriveDepart)
{
}

编写一个搜索列表的方法,检查每个 Reservation 记录对象中包含的 LocalDateRange 对象,并询问它是否与我们的目标日期范围重叠。

    boolean isDateRangeTaken ( List < Reservation > reservationList , LocalDateRange dateRange )
    {
        boolean taken = false;
        for ( Reservation reservation : reservationList )
        {
            if ( reservation.arriveDepart().overlaps( dateRange ) ) { return true; }
        }
        return taken;
    }

执行该代码。

        LocalDate today = LocalDate.now( ZoneId.of( "America/Edmonton" ) );
        List < Reservation > reservationList =
                List.of(
                        new Reservation( "Alex Test" , "abrdwa@gmail.com" , 99323223 , LocalDateRange.of( today.plusDays( 10 ) , today.plusDays( 13 ) ) ) ,
                        new Reservation( "Criss Test2" , "acdef@gmail.com" , 47825433 , LocalDateRange.of( today.plusDays( 10 ) , today.plusDays( 15 ) ) ) ,
                        new Reservation( "Frank Test3" , "abcde@gmail.com" , 41722210 , LocalDateRange.of( today.plusDays( 10 ) , today.plusDays( 17 ) ) ) ,
                        new Reservation( "Elea Test4" , "abcd@gmail.com" , 99321312 , LocalDateRange.of( today.plusDays( 10 ) , today.plusDays( 19 ) ) ) ,
                        new Reservation( "Monica Test5" , "abc@hotmail.com" , 99922223 , LocalDateRange.of( today.plusDays( 10 ) , today.plusDays( 19 ) ) )
                );

        LocalDateRange near = LocalDateRange.of( today.plusDays( 11 ) , today.plusDays( 13 ) );
        boolean isNearDateRangeTaken = this.isDateRangeTaken( reservationList , near );
        System.out.println( near + " is taken: " + isNearDateRangeTaken );

        LocalDateRange far = LocalDateRange.of( today.plusDays( 180 ) , today.plusDays( 183 ) );
        boolean isFarDateRangeTaken = this.isDateRangeTaken( reservationList , far );
        System.out.println( far + " is taken: " + isFarDateRangeTaken );

运行时。

2021-02-28/2021-03-02 is taken: true
2021-08-16/2021-08-19 is taken: false

我们可以使用流和 lambda 语法来搜索列表。

        LocalDateRange target = LocalDateRange.of( today.plusDays( 18 ) , today.plusDays( 22 ) );
        List < Reservation > hits =
                reservationList
                        .stream()
                        .filter( reservation -> reservation.arriveDepart().overlaps( target ) )
                        .toList();
        System.out.println( "Overlapping " + target + " is: " + hits );

运行时,我们发现列表中的最后两个元素是命中。

Overlapping 2021-03-07/2021-03-11 is: [Reservation[customerName=Elea Test4, customerEmail=abcd@gmail.com, id=99321312, arriveDepart=2021-02-27/2021-03-08], Reservation[customerName=Monica Test5, customerEmail=abc@hotmail.com, id=99922223, arriveDepart=2021-02-27/2021-03-08]]


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 2016-04-21
    • 2017-06-19
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    相关资源
    最近更新 更多