I am trying to create a scheduling, where I can only get the inputted time and name of schedule.
I wanted to put the schedule in a List
but if there's no other schedule, the List should be add a new empty schedule starting from 6:00 AM
if there's no other early time.
I have ObservableList<DataClass>
, it contains LocalTime
and some String
.
Example 1: Let's say the list contains 3 items:
[04:00 AM] [Some String]
[06:30 AM] [Some String]
[05:00 PM] [Some String]
I want to add the missing time in the list from 4:00 AM
to 5:00 PM
, so the list will be:
[04:00 AM] [Some String]
[05:00 AM] [Some String]
[06:30 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]
Example 2: Let's say the list contains 2 items:
[08:30 AM] [Some String]
[02:00 PM] [Some String]
I want to add the missing time in the list from 6:00 AM
to 5:00 PM
, so the list will be:
[06:00 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]
Example 3: Let's say the list contains 1 items:
[08:00 PM] [Some String]
I want to add the missing time in the list from 6:00 AM
to 8:00 PM
, so the list will be.
[06:00 AM] [Some String]
[07:00 AM] [Some String]
[08:00 AM] [Some String]
[09:00 AM] [Some String]
[10:00 AM] [Some String]
[11:00 AM] [Some String]
[12:00 PM] [Some String]
[01:00 PM] [Some String]
[02:00 PM] [Some String]
[03:00 PM] [Some String]
[04:00 PM] [Some String]
[05:00 PM] [Some String]
[06:00 PM] [Some String]
[07:00 PM] [Some String]
[08:00 PM] [Some String]
The time should be start at 06:00 AM
if there's no other early time, otherwise the time will start at that early time.
The time should be end at 5:00 PM
if there's no other time, otherwise the time will end at that specific time, I want to add only HOUR
like increment
hour so there shouldn't be 6:30
, 5:30
unless it is manually inputted.
I am thinking of the following logic but I can't proceed because of lock on idea.
Sort the list base on the time from AM to PM to get the first time
Check if the time of the first data is equal or less than 6:00 AM
if true, then start from that time and continue adding the missing time until the 5:00 PM or the last time is reach.
if false, then start from 6:00 AM and continue adding the missing time until the 5:00 PM or the last time is reach.
the below code is currently what I have and puzzling.
private void fillTheList(){
ObservableList<DataClass> data = FXCollections.observableArrayList();
Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);
data.add(new DataClass(convertTime("05:00 PM"), "Sample Content"));
data.add(new DataClass(convertTime("06:30 AM"), "Sample Content"));
FXCollections.sort(data,comparator); //Sort the list from AM to PM
for (DataClass list : data){
if(list.getLocalTime().isBefore(LocalTime.of(6,0))){
//The time is less than 6:00 AM then it should start here and Add the missing time but I don't know what to do next...
}else{
//the time is not less than 6:00 AM... I don't know what to do next..
}
}
FXCollections.sort(data,comparator); //Sort the list from AM to PM again
}
private LocalTime convertTime(String timeString){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");
return LocalTime.parse(timeString, formatter);
}
PS: I'm not actually sure what I'm going to ask so feel free to suggest an edit if necessary.
UPDATE: DataClass.class
public class DataClass {
private LocalTime localTime;
private String content;
public DataClass(LocalTime localTime, String content){
this.localTime = localTime;
this.content = content;
}
public LocalTime getLocalTime(){
return localTime;
}
public String getContent(){
return content;
}
}
You're well on the way yourself. Furthermore azro is correct that you need to find the min and max hour to consider for insertion by comparing to the min and max time already in the data. Jai is correct that you should check whether a time is already in the list before inserting it and that a stream is convenient for this purpose. My version uses an int
for iterating over the hours, but all the others are correct that a LocalTime
works too.
int minHour = 6;
int maxHour = 17;
if (! data.isEmpty()) {
// adjust min and max from list contents
int minExisintgHour = data.get(0).getLocalTime().getHour();
if (minExisintgHour < minHour) {
// if the list already contained 4:00 or 4:30,
// we only need to add hours from 5, so add 1
minHour = minExisintgHour + 1;
}
int maxExisintgHour = data.get(data.size() - 1).getLocalTime().getHour();
if (maxExisintgHour > maxHour) {
maxHour = maxExisintgHour;
}
}
for (int hour = minHour; hour <= maxHour; hour++) {
LocalTime time = LocalTime.of(hour, 0);
boolean alreadyInData = data.stream().anyMatch(d -> d.getLocalTime().equals(time));
if (! alreadyInData) {
data.add(new DataClass(time, "Added beacuse time was missing"));
}
}
I am assuming that you are sorting the list before and after the above code as in the question. Sorting before could be omitted if you do a linear traversal for min and max (something a couple of streams can do too).
Sample resulting list:
[06:00 AM] [Added beacuse time was missing]
[06:30 AM] [Sample Content]
[07:00 AM] [Added beacuse time was missing]
[08:00 AM] [Added beacuse time was missing]
[09:00 AM] [Added beacuse time was missing]
[10:00 AM] [Added beacuse time was missing]
[11:00 AM] [Added beacuse time was missing]
[12:00 PM] [Added beacuse time was missing]
[01:00 PM] [Added beacuse time was missing]
[02:00 PM] [Added beacuse time was missing]
[03:00 PM] [Added beacuse time was missing]
[04:00 PM] [Added beacuse time was missing]
[05:00 PM] [Sample Content]
You have to follow these steps
get the value for start, it will be 06AM
or the first value of the list, it depends which one is first
get the value for end, it's just the 2nd value
i.isBefore(end.plusHours(1))
and not i.isBefore(end)
because you need the end
element to be included ObservableList<DataClass> data = FXCollections.observableArrayList();
Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);
data.add(new DataClass(convertTime("05:00 PM"), "Sample Content"));
data.add(new DataClass(convertTime("06:30 AM"), "Sample Content"));
FXCollections.sort(data,comparator); //Sort the list from AM to PM
// 1. & 2.
LocalTime begin = LocalTime.of(6,0);
if(data.get(0).getLocalTime().isBefore(begin)){
begin = data.get(0).getLocalTime();
}
LocalTime end = LocalTime.of(17,0);
if(end.isBefore(data.get(data.size()-1).getLocalTime())){
end = data.get(data.size()-1).getLocalTime();
}
// 3.
data.clear();
// 4. & 5.
for(LocalTime i = begin.withMinute(0); !i.isAfter(end); i = i.plusHours(1)){
data.add(new DataClass(i, "Sample Content"));
}
// 6.
FXCollections.sort(data,comparator); //Sort the list from AM to PM again
System.out.println(data);
// [06:00, 07:00, 08:00, 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, 17:00]
Not totally sure what you need, but this may be what you need:
ObservableList<DataClass> data = FXCollections.observableArrayList();
// Need to specify the period that you want the entries to be filled
private void fill(LocalTime from, LocalTime to) {
// Keep adding new entries until we have reached the end
while (!from.isAfter(to)) {
// We need a final variable for stream()
final LocalTime temp = from;
// If data does not contain any time that is equivalent to this time
if (data.stream().noneMatch(d -> temp.equals(d.getLocalTime()))) {
data.add(new DataClass(temp, "Hello World"));
}
// Increment the time by an hour, and wait for next loop cycle
from = from.plusHours(1);
}
}
Unless you want to display the data in a sorted manner, there isn't any point in sorting.
This implementation does not stop you from passing in a from
and to
with minute (or seconds) value.
If you need it to be in purely hour units, then this can be changed to:
ObservableList<DataClass> data = FXCollections.observableArrayList();
// Need to specify the period that you want the entries to be filled
private void fill(int fromHour, int toHour) {
LocalTime from = LocalTime.of(fromHour, 0);
LocalTime to = LocalTime.of(toHour, 0);
// Keep adding new entries until we have reached the end
while (!from.isAfter(to)) {
// We need a final variable for stream()
final LocalTime temp = from;
// If data does not contain any time that is equivalent to this time
if (data.stream().noneMatch(d -> temp.equals(d.getLocalTime()))) {
data.add(new DataClass(temp, "Hello World"));
}
// Increment the time by an hour, and wait for next loop cycle
from = from.plusHours(1);
}
}
This will force the two boundary values to have only hour values.
Proceed as follows
ObservableList<DataClass> data = ...
LocalTime lowerBound = LocalTime.of(6, 0); // or some other input
LocalTime upperBound = LocalTime.of(12 + 5, 0); // or some other input
Comparator<DataClass> comparator = Comparator.comparing(DataClass::getLocalTime);
FXCollections.sort(data, comparator);
int size = data.size();
int index = 0;
while (!lowerBound.isAfter(upperBound)) {
// find inserting index
while (index < size && data.get(index).getLocalTime().isBefore(lowerBound)) {
index++;
}
// insert, if not already in list
if (index >= size || !data.get(index).getLocalTime().equals(lowerBound)) {
data.add(index, new DataClass(lowerBound, "Inserted"));
size++;
}
lowerBound = lowerBound.plusHours(1);
index++;
}
Note that for smaller steps and bigger number of elements in the list the performance of the code is suboptimal, since adding to the middle of the list runs in O(n)
, so the resulting complexity would be O(i + i*n + n*log(n))
where i
is the number of insertions and n
is the initial size of the list.
To improve this, you could add all the new elements to the end of the list and then use the merge step from mergesort once, which would result in runtime O(i+n*log(n))
:
final int size = data.size();
int index = 0;
while (!lowerBound.isAfter(upperBound)) {
// find inserting index
while (index < size && data.get(index).getLocalTime().isBefore(lowerBound)) {
index++;
}
// insert, if not already in list
if (index >= size || !data.get(index).getLocalTime().equals(lowerBound)) {
data.add(new DataClass(lowerBound, "Inserted"));
} else {
index++;
}
lowerBound = lowerBound.plusHours(1);
}
// merge
DataClass[] merged = new DataClass[data.size()];
int insertionIndex = 0;
int index1 = 0;
int index2 = size;
while (index1 < size && index2 < merged.length) {
DataClass v1 = data.get(index1);
DataClass v2 = data.get(index2);
if (v2.getLocalTime().isBefore(v1.getLocalTime())) {
merged[insertionIndex] = v2;
index2++;
} else {
merged[insertionIndex] = v1;
index1++;
}
insertionIndex++;
}
// copy remaining
while (index1 < size) {
merged[insertionIndex++] = data.get(index1++);
}
while (index2 < merged.length) {
merged[insertionIndex++] = data.get(index2++);
}
data.setAll(merged);
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.