2

I have a list of sorted OffsetDateTime dates:

[2021-05-21T11:00-04:00, 2021-05-21T12:00-04:00, 2021-05-21T13:00-04:00, 2021-05-21T14:00-04:00, 2021-05-21T15:00-04:00, 2021-05-21T15:30-04:00, 2021-05-21T15:45-04:00, 2021-05-21T17:00-04:00]

I'd like to create a list of objects with a start and end date like the following:

{start: 2021-05-21T11:00-04:00, end: 2021-05-21T12:00-04:00}

{start: 2021-05-21T12:00-04:00, end: 2021-05-21T13:00-04:00}

{start: 2021-05-21T13:00-04:00, end: 2021-05-21T14:00-04:00}

{start: 2021-05-21T14:00-04:00, end: 2021-05-21T15:00-04:00}

{start: 2021-05-21T15:00-04:00, end: 2021-05-21T15:30-04:00}

{start: 2021-05-21T15:30-04:00, end: 2021-05-21T15:45-04:00}

{start: 2021-05-21T15:45-04:00, end: 2021-05-21T17:00-04:00}

Note that the start of the next date is the end of the previous date (Except first and last)

What I have so far...

    // Create List<AppointmentAvailabilityBlock>
    List<AppointmentAvailabilityBlock> appointmentAvailabilityBlockList = new ArrayList<>();
    for (int i = 0; i < sortedTimes.size(); i+=2) {
        
        OffsetDateTime start = sortedTimes.get(i);
        OffsetDateTime end = sortedTimes.get(i+1);
        appointmentAvailabilityBlockList.add(new AppointmentAvailabilityBlock(start, end));
        
    }

But this outputs:

2021-05-21T11:00-04:00 2021-05-21T12:00-04:00

2021-05-21T13:00-04:00 2021-05-21T14:00-04:00

2021-05-21T15:00-04:00 2021-05-21T15:30-04:00

2021-05-21T15:45-04:00 2021-05-21T17:00-04:00

Machavity
  • 30,841
  • 27
  • 92
  • 100
wazowski
  • 115
  • 8

3 Answers3

3
public void createObjects(List<OffsetDateTime> dates){
   for(int i=0;i<dates.size()-1;i++){
     Pair<OffsetDateTime, OffsetDateTime> date = new Pair<>(dates.get(i), dates.get(i+1));
     // handle each object as you require
     call_my_function(date);
   }
}
3

If you wanna use a more modern approach via streams. You could find a better solution there.

In short, your code might looks like the next:

 IntStream.range(1, sortedTimes.size())
             .mapToObj(i -> new AppointmentAvailabilityBlock(sortedTimes.get(i-1), sortedTimes.get(i)))
             .forEach(System.out::println)
Volodya Lombrozo
  • 2,325
  • 2
  • 16
  • 34
3

There are several options that you could use depending on whether you wanted to store the results or print them. Before that, here are some points to consider:

  • in the provided answers, .collect(Collectors.toList()) may be replaced with .forEach(System.out::println) if all you want is to print them. The assignment to the list result must also be removed.
  • List.subList comes in handy here. But each subList is simply a view into the original list. So any changes to subList will change the original. This can be solved by passing the subList as an argument to ArrayList<>()
  • the results shown are based on the default toString display for OffsetDateTime. To change that you can apply a DateTimeFormatter within the stream construct.

Just print the values in pairs using a stream and a subList

IntStream.range(1, sortedTimes.size())
        .mapToObj(i -> sortedTimes.subList(i - 1, i + 1))
        .forEach(System.out::println);

Prints

[2021-05-21T11:00-04:00, 2021-05-21T12:00-04:00]
[2021-05-21T12:00-04:00, 2021-05-21T13:00-04:00]
[2021-05-21T13:00-04:00, 2021-05-21T14:00-04:00]
[2021-05-21T14:00-04:00, 2021-05-21T15:00-04:00]
[2021-05-21T15:00-04:00, 2021-05-21T15:30-04:00]
[2021-05-21T15:30-04:00, 2021-05-21T15:45-04:00]
[2021-05-21T15:45-04:00, 2021-05-21T17:00-04:00]

Storing the pairs in a List of lists to be processed later. The subList was passed to an ArrayList as explained above.

List<List<OffsetDateTime>> list = IntStream
        .range(1, sortedTimes.size())
        .mapToObj(i -> new ArrayList<>(sortedTimes.subList(i - 1, i + 1)))
        .collect(Collectors.toList());

A little more elaborate printing and storing in a list.

List<String> listString = IntStream.range(1, sortedTimes.size())
        .mapToObj(i -> sortedTimes.subList(i - 1, i + 1))
        .map(s->"Start: " + s.get(0) + " - End: " + s.get(1))
        .collect(Collectors.toList());
list.forEach(System.out.println);

Prints

Start: 2021-05-21T11:00-04:00 - End: 2021-05-21T12:00-04:00
Start: 2021-05-21T12:00-04:00 - End: 2021-05-21T13:00-04:00
Start: 2021-05-21T13:00-04:00 - End: 2021-05-21T14:00-04:00
Start: 2021-05-21T14:00-04:00 - End: 2021-05-21T15:00-04:00
Start: 2021-05-21T15:00-04:00 - End: 2021-05-21T15:30-04:00
Start: 2021-05-21T15:30-04:00 - End: 2021-05-21T15:45-04:00
Start: 2021-05-21T15:45-04:00 - End: 2021-05-21T17:00-04:00

And just for completion, here is how the List<OffsetDateTime> was created

List<String> sortedStringTimes = new ArrayList<>(List.of("2021-05-21T11:00-04:00",
                "2021-05-21T12:00-04:00", "2021-05-21T13:00-04:00",
                "2021-05-21T14:00-04:00", "2021-05-21T15:00-04:00",
                "2021-05-21T15:30-04:00", "2021-05-21T15:45-04:00",
                "2021-05-21T17:00-04:00"));

DateTimeFormatter df = DateTimeFormatter.ISO_OFFSET_DATE_TIME;

// toList() as used below was introduced in Java 16
List<OffsetDateTime> sortedTimes = sortedStringTimes.stream()
        .map(odt->OffsetDateTime.from(df.parse(odt))).toList();
  
WJS
  • 36,363
  • 4
  • 24
  • 39