简体   繁体   中英

how to check if an object with a certain date already exists in a ArrayList

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.

  1. Hotel class contains ArrayList of Reservations but you don't modify it directly..
  2. 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".
  3. The term "already made" needs to be defined more clearly. Do you mean the same reservation is already made? Or you mean that you want to check that it doesn't conflict with other reservations? If the latter, then you need to loop through the existing reservations and compare the dates start and end times with each.

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


About java.time

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM