如何检查具有特定日期的对象是否已存在于 ArrayList 中



我有点被困在我正在做的项目中。所以我正在写一个酒店类(家长)和一个预订类(孩子)。

在我的预订类中,我正在创建要在酒店进行的新预订。我的保留构造函数正在接受以下参数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;

}

这是我会采取的高级方法。

  1. Hotel类包含Reservations的 ArrayList,但您不会直接修改它。
  2. Hotel类有一个boolean addReservation(Reservation)方法,该方法采用Reservation并将其添加到数组中并返回 true,如果它"已经制作"则返回 false。
  3. "已经制造"一词需要更明确地界定。您的意思是已经进行了相同的预订吗?或者你的意思是你想检查它是否与其他预订不冲突?如果是后者,则需要循环浏览现有预留,并将日期的开始和结束时间与每个日期进行比较。

首先,您必须考虑什么是相同的保留。所有字段都相同,包括确切的日期?还是重叠日期?或者只是姓名和电子邮件?根据此情况,将覆盖预留中的相等方法。 您可以添加支票:

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

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

LocalDateRange

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

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

因此,您的Reservation类应包含开始日期和停止日期的成员字段LocalDateRange

如果使用 Java 16 或更高版本,我们可以更简要地编写您的Reservation类作为记录。在记录中,编译器隐式创建构造函数、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 及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.DateCalendarSimpleDateFormat

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

Joda-Time项目现在处于维护模式,建议迁移到 java.time 类。

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

从哪里获得java.time类?

Java SE 8、Java SE 9、Java SE
  • 10、Java SE 11及更高版本 - 标准 Java API 的一部分,具有捆绑实现。
    • Java 9带来了一些小功能和修复。
  • Java SE 6 和 Java
  • SE7
    • 大多数java.time功能在ThreeTen-Backport中向后移植到 Java 6 和 7。
  • Android
    • 更高版本的 Android (26+) 捆绑了java.time类的实现。
    • 对于早期的 Android(<26),API 脱糖过程带来了最初未内置于 Android 中的java.time功能的子集。
      • 如果脱糖不能提供你需要的东西,ThreeTenABP项目将ThreeTen-Backport(如上所述)适应Android。请参阅如何使用ThreeTenABP...

ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

最新更新