I'm kinda stuck in a project im doing. So I'm writing a Hotel class (parent) and a Reservation class (child).
In my reservation class im creating new reservations to be made at the Hotel. My Reservation Constructor is taking the following arguments Reservation(String name, String Email, int phonenum, LocalDate fromDate, LocalDate toDate).
However, I now want to check if a reservation is already made when creating a new reservation. All my objects is kept in an ArrayList
, but I'm not really sure how to go about this, given the way I've constructed the dates. Any pinpointers would be much appreciated!
EDIT:
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;
}
Here's a high level approach I would take.
Hotel
class contains ArrayList of Reservations
but you don't modify it directly.. Hotel
class has an boolean addReservation(Reservation)
method that takes a Reservation
and either adds it to the array and returns true or returns false if it's "already made". First of all you have to think about what is the same reservation. All the fields are the same including the exact date? Or overlapping date? Or just the name and email? Depending on this overwrite the equal method in Reservation. Than you could add a check:
if(reservations.contains(newReservationAttempt){
//do whatever you want, return a boolean inside a method or
throw new ReservationAlreadyExistException()
}
An other possibility would be to check criteria with Java Streams and any match.
LocalDateRange
I suggest you add the ThreeTen-Extra library to your project. This library brings classes that add to the java.time functionality built into Java 8 and later. Indeed, both this library and java.time are led by the same man, Stephen Colebourne.
In particular, ThreeTen-Extra offers the LocalDateRange
class. This class represents a span of time as a pair of LocalDate
objects. The class offers handy methods for comparison, such as abuts
, overlaps
, and so on.
So your Reservation
class should contain a member field of LocalDateRange
for the start and stop dates.
If using Java 16 or later, we can write your Reservation
class more briefly as a record . In a record, the compiler implicitly creates the constructor, getters, equals
& hashCode
, and toString
.
package work.basil.example.hotel;
import org.threeten.extra.LocalDateRange;
public record Reservation(String customerName , String customerEmail , int id , LocalDateRange arriveDepart)
{
}
Write a method to search a list, examining each Reservation
record object for its contained LocalDateRange
object, and ask if it overlaps with our target date range.
boolean isDateRangeTaken ( List < Reservation > reservationList , LocalDateRange dateRange )
{
boolean taken = false;
for ( Reservation reservation : reservationList )
{
if ( reservation.arriveDepart().overlaps( dateRange ) ) { return true; }
}
return taken;
}
Exercise that code.
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 );
When run.
2021-02-28/2021-03-02 is taken: true
2021-08-16/2021-08-19 is taken: false
We can use streams and lambda syntax to search the list.
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 );
When run we find the last two elements in the list are 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]]
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .
The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes. Hibernate 5 & JPA 2.2 support java.time .
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.