如何解决如何检查具有特定日期的对象是否已存在于 ArrayList 中
我有点困在我正在做的一个项目中。所以我正在编写一个 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(15)));
reservations.add(new Reservation("Frank Test3","abcde@gmail.com",41722210,LocalDate.Now().plusDays(15)));
reservations.add(new Reservation("Elea Test4","abcd@gmail.com",99321312,LocalDate.Now().plusDays(15)));
reservations.add(new Reservation("Monica Test5","abc@hotmail.com",99922223,LocalDate.Now().plusDays(15)));
return reservations;
}
解决方法
这是我会采用的高级方法。
-
Hotel
类包含Reservations
的 ArrayList 但您不直接修改它.. -
Hotel
类有一个boolean addReservation(Reservation)
方法,它接受一个Reservation
并将其添加到数组中并返回 true 或如果它“已经制作”则返回 false。 - 需要更清楚地定义“已经制造”一词。您的意思是已经进行了相同的预订?或者您的意思是要检查它是否与其他保留不冲突?如果是后者,则您需要遍历现有的预订并将日期开始和结束时间与每个预订进行比较。
首先你要考虑什么是相同的预订。所有字段都相同,包括确切日期?还是日期重叠?还是只有姓名和电子邮件?根据这个覆盖 Reservation 中的 equal 方法。 比你可以添加一个检查:
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
对象。该类提供了方便的比较方法,例如 abuts
、overlaps
等。
因此,您的 Reservation
类应该包含一个成员字段 LocalDateRange
,用于开始和结束日期。
如果使用 Java 16 或更高版本,我们可以将您的 Reservation
类更简短地编写为 record。在记录中,编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
。
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,today.plusDays( 15 ) ) ),new Reservation( "Frank Test3","abcde@gmail.com",41722210,today.plusDays( 17 ) ) ),new Reservation( "Elea Test4","abcd@gmail.com",99321312,today.plusDays( 19 ) ) ),new Reservation( "Monica Test5","abc@hotmail.com",99922223,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.Date
、Calendar
和 SimpleDateFormat
。
要了解更多信息,请参阅 Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为 JSR 310。
现在位于 Joda-Time 的 maintenance mode 项目建议迁移到 java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC driver 或更高版本的 JDBC 4.2。不需要字符串,不需要 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 SE 7
- 大部分 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。
-
Android
- 更高版本的 Android (26+) 捆绑了 java.time 类的实现。
- 对于早期的 Android (API desugaring 的进程带来了 subset of the java.time 最初未内置于 Android 中的功能。
- 如果脱糖不能满足您的需求,ThreeTenABP 项目会将 ThreeTen-Backport(上文提到的)适配到 Android。见How to use ThreeTenABP…。
ThreeTen-Extra 项目使用附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在此处找到一些有用的类,例如 Interval
、YearWeek
、YearQuarter
和 more。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。