I denne oppgaven skal du implementere klasser og metoder for å håndtere en dagsplan med tidsrom, f.eks. avtaler. Klassen oppgitt i oppgave 1 a) kan brukes som en del av implementasjonen din. Husk at alle metoder kan brukes i implementasjonen av andre. Oppgave a)Du skal implementere en klasse TimeSlot for å representere et tidsrom innenfor en dag, f.eks. en avtale. Et TimeSlot-objekt har en beskrivelse (tekst), et start- og sluttidspunkt (time og minutt) og en varighet (minutter). Ingen av disse dataene skal kunne endres etter at TimeSlot-objektet er opprettet. Du velger selv hvordan disse dataene skal representeres og hvilke hjelpemetoder som evt. trengs. Merk at varighet kan beregnes fra starttidspunkt og sluttidspunkt, evt. at sluttidspunkt kan beregnes fra starttidspunkt og varighet. Implementer følgende konstruktører og metoder: - TimeSlot(String description, int hours, int minutes, int duration): initialiserer med oppgitt beskrivelse og starttidspunkt (timer og minutter) og varighet (minutter). F.eks. vil new TimeSlot(”TDT4100-forelesning”, 10, 15, 105) representere en TDT4100-forelesning i tidsrommet 10:15-12:00.
- String toString(): returnerer en String på formen beskrivelse@start-slutt hvor start og slutt er på formen tt:mm (altså to siffer pr. tall). Dersom toString()-metoden kalles på TimeSlot-objektet fra forrige punkt skal det gi ”TDT4100-forelesning@10:15-12:00”.
- DayTime getStartTime(): returnerer starttidspunktet som et DayTime-objekt (se oppgave 1).
- DayTime getEndTime(): returnerer sluttidspunktet som et DayTime-objekt (se oppgave 1).
- int getDuration(): returnerer varighet i minutter
Expand |
---|
| Det er ikke viktig å ta hensyn til overgangen mellom dager, dvs. interval som går over midnatt. Vi velger å representere start- og sluttidspunktene som antall minutter siden midnatt. Dette gjør mange av beregningene siden lettere. Et alternativ er å ha to DayTime-felt i stedet eller int-felt for start/slutt-time og –minutter. Code Block |
---|
private static int asHours (int minutes) { return minutes / 60;}
private static int asMinutes(int minutes) { return minutes % 60;}
private String description;
private int startTime, endTime;
public TimeSlot(String description, int hours, int minutes, int duration) {
this.description = description;
this.startTime = hours * 60 + minutes;
this.endTime = this.startTime + duration;
}
private String twoDigits(int i) {
return (i < 10 ? "0" : "") + i;
}
public String toString() {
return description + "@" + twoDigits(asHours(startTime)) + ":" + twoDigits(asMinutes(startTime)) + "-" + twoDigits(asHours(endTime)) + ":" + twoDigits(asMinutes(endTime));
}
public DayTime getStartTime() {
return new DayTime(asHours(startTime), asMinutes(startTime));
}
public DayTime getEndTime() {
return new DayTime(asHours(endTime), asMinutes(endTime));
}
public int getDuration() {
return endTime - startTime;
}
public String getDescription() {
return description;
} |
|
Oppgave b)Implementer følgende metoder: - boolean contains(int hours, int minutes): returnerer om dette TimeSlot-objektet inneholder tidspunktet angitt med hours og minutes. Merk at sluttidspunktet regnes ikke som å være inneholdt i tidsrommet. Dette betyr at new TimeSlot(”…”, 8, 0, 30).contains(8, 0) skal gi true, mens new TimeSlot(”…”, 8, 0, 30).contains(8, 30) skal gi false.
- boolean overlaps(TimeSlot timeSlot): returnerer om dette TimeSlot-objektet overlapper med det angitte TimeSlot-objektet, dvs. om det finnes et tidspunkt som begge inneholder.
Expand |
---|
| Code Block |
---|
public boolean contains(int hours, int minutes) {
minutes = hours * 60 + minutes;
return startTime <= minutes && endTime > minutes;
}
public boolean overlaps(TimeSlot other) {
return startTime < other.endTime && endTime > other.startTime;
} |
En alternativ strategi er å sjekke om start- eller sluttidspunktet ligger inni den andre eller omvendt. |
Oppgave c) TimeSlot-klassen skal støtte sortering. TimeSlot-objektet med tidligst starttidspunkt sorteres først, og dersom starttidspunktene er like, så skal det med tidligst sluttidspunkt sorteres først. Forklar og implementer nødvendig kode. Expand |
---|
| Dersom klassen implementerer Comparable spesialisert til samme klasse, så kan instansene sorteres vha. Java sin innebygde Collections.sort-metode. Code Block |
---|
public class TimeSlot implements Comparable<TimeSlot> {
...
public int compareTo(TimeSlot other) {
// negativ diff betyr mindre enn
int diff = startTime - other.startTime;
if (diff == 0) {
diff = endTime - other.endTime;
}
return diff;
}
} |
|
Oppgave d)Du skal implementere en klasse DayPlan, for å holde oversikt over alle avtalene (altså TimeSlot-objekter) for en dag, bl.a. gi muligheten til å legge til og fjerne TimeSlot-objekter. Velg selv hvilke felt og evt. hjelpemetoder som trengs. Implementer følgende metoder: - void addTimeSlot(TimeSlot timeSlot): legger det angitte tidsrommet til denne dagsplanen
- void removeTimeSlot(TimeSlot timeSlot): fjerner det angitte tidsrommet fra denne dagsplanen
- TimeSlot getTimeSlotAt(int hours, int minutes): returnerer det tidligste tidsrommet som inneholder tidspunktet angitt med hours og minutes, ellers null.
Expand |
---|
| Code Block |
---|
private List<TimeSlot> timeSlots = new ArrayList<TimeSlot>();
public void addTimeSlot(TimeSlot timeSlot) {
timeSlots.add(timeSlot);
Collections.sort(timeSlots);
}
public void removeTimeSlot(TimeSlot timeSlot) {
timeSlots.remove(timeSlot);
}
public TimeSlot getTimeSlotAt(int hours, int minutes) {
for (TimeSlot timeSlot : timeSlots) {
if (timeSlot.contains(hours, minutes)) {
return timeSlot;
}
}
return null;
} |
|
Oppgave e) Implementer følgende to metoder for tidsplanlegging: - boolean containsOverlapping(): returnerer om det finnes overlappende tidsrom i denne dagsplanen.
- Collection<TimeSlot> getFreeTime(): returnerer en samling TimeSlot-objekter som representerer fritiden en har i løpet av en dag, dvs. tidsrommene som denne dagsplanen ikke dekker.
For begge disse metodene kan det være lurt å definere hjelpemetoder for å gjøre løsningen ryddigere. Expand |
---|
| Disse to metodene er litt fiklete, så vi er ikke så nøye på detaljene. Vi kan utnytte at lista er sortert. Dersom duplikater ikke er lov, så trenger en strengt tatt kun en enkel løkke som sjekker for overlapp med nabo-elementet. Med duplikater må en sjekke mot første element etter/før som ikke er samme element: Code Block |
---|
public boolean containsOverlapping() {
for (int i = 0; i < timeSlots.size(); i++) {
TimeSlot timeSlot = timeSlots.get(i);
for (int j = i + 1; j < timeSlots.size(); j++) {
TimeSlot otherTimeSlot = timeSlots.get(j);
if (timeSlot != otherTimeSlot) {
return timeSlot.overlaps(otherTimeSlot);
}
// alternativt, dersom lista ikke er sortert
if (timeSlot != otherTimeSlot && timeSlot.overlaps(otherTimeSlot)) {
return true;
}
}
}
return false;
}
private static void addTimeSlotIfNonEmpty(Collection<TimeSlot> timeSlots, DayTime startTime, DayTime endTime) {
int duration = (endTime.hours * 60 + endTime.minutes) - (startTime.hours * 60 + startTime.minutes);
if (duration > 0) {
timeSlots.add(new TimeSlot(null, startTime.hours, startTime.minutes, duration));
}
}
public Collection<TimeSlot> getFreeTime() {
Collection<TimeSlot> freeTime = new ArrayList<TimeSlot>();
TimeSlot previous = new TimeSlot(null, 0, 0, 0);
for (TimeSlot timeSlot : getAllTimeSlots()) {
DayTime startTime = timeSlot.getStartTime();
addTimeSlotIfNonEmpty(freeTime, previous.getEndTime(), startTime);
DayTime endTime = timeSlot.getEndTime();
if (! previous.contains(endTime.hours, endTime.minutes)) {
previous = timeSlot;
}
}
addTimeSlotIfNonEmpty(freeTime, previous.getEndTime(), new DayTime(24, 0));
return freeTime;
}
|
Et alternative er å gå gjennom alle tidspunkt i døgnet og “samle” minuttene som ikke er inneholdt i noe tidsintervall i nye tidsintervall som legges til resultatlista. |
|