diff --git a/java-gym-master.iml b/java-gym-master.iml
index e5d2daf..5dfd50f 100644
--- a/java-gym-master.iml
+++ b/java-gym-master.iml
@@ -8,5 +8,6 @@
+
\ No newline at end of file
diff --git a/src/ru/yandex/practicum/gym/Coach.java b/src/ru/yandex/practicum/gym/Coach.java
index dce0d7c..026bf00 100644
--- a/src/ru/yandex/practicum/gym/Coach.java
+++ b/src/ru/yandex/practicum/gym/Coach.java
@@ -4,12 +4,12 @@
public class Coach {
- //фамилия
- private String surname;
- //имя
- private String name;
- //отчество
- private String middleName;
+ // фамилия
+ private final String surname;
+ // имя
+ private final String name;
+ // отчество
+ private final String middleName;
public Coach(String surname, String name, String middleName) {
this.surname = surname;
@@ -17,19 +17,6 @@ public Coach(String surname, String name, String middleName) {
this.middleName = middleName;
}
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Coach coach = (Coach) o;
- return Objects.equals(surname, coach.surname) && Objects.equals(name, coach.name) && Objects.equals(middleName, coach.middleName);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(surname, name, middleName);
- }
-
public String getSurname() {
return surname;
}
@@ -41,4 +28,20 @@ public String getName() {
public String getMiddleName() {
return middleName;
}
-}
+
+ // Нужно для корректной работы HashMap в getCountByCoaches()
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Coach coach = (Coach) o;
+ return Objects.equals(surname, coach.surname)
+ && Objects.equals(name, coach.name)
+ && Objects.equals(middleName, coach.middleName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(surname, name, middleName);
+ }
+}
\ No newline at end of file
diff --git a/src/ru/yandex/practicum/gym/TimeOfDay.java b/src/ru/yandex/practicum/gym/TimeOfDay.java
index c567fec..d0669f9 100644
--- a/src/ru/yandex/practicum/gym/TimeOfDay.java
+++ b/src/ru/yandex/practicum/gym/TimeOfDay.java
@@ -4,16 +4,25 @@
public class TimeOfDay implements Comparable {
- //часы (от 0 до 23)
- private int hours;
- //минуты (от 0 до 59)
- private int minutes;
+ // часы (от 0 до 23)
+ private final int hours;
+ // минуты (от 0 до 59)
+ private final int minutes;
public TimeOfDay(int hours, int minutes) {
+
this.hours = hours;
this.minutes = minutes;
}
+ public int getHours() {
+ return hours;
+ }
+
+ public int getMinutes() {
+ return minutes;
+ }
+
@Override
public int compareTo(TimeOfDay o) {
if (hours != o.hours) return hours - o.hours;
@@ -32,12 +41,4 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(hours, minutes);
}
-
- public int getHours() {
- return hours;
- }
-
- public int getMinutes() {
- return minutes;
- }
-}
+}
\ No newline at end of file
diff --git a/src/ru/yandex/practicum/gym/Timetable.java b/src/ru/yandex/practicum/gym/Timetable.java
index 48a1e2a..0229af3 100644
--- a/src/ru/yandex/practicum/gym/Timetable.java
+++ b/src/ru/yandex/practicum/gym/Timetable.java
@@ -4,17 +4,127 @@
public class Timetable {
- private /* как это хранить??? */ timetable;
+ // O(1) получить отсортированный список занятий за день
+ private Map> dayCache;
+
+ // O(1) получить занятия по дню и времени
+ private Map>> byDayAndTime;
+
+ // сразу считаем тренировки тренеров при добавлении
+ private Map coachesCounter;
+
+ public Timetable() {
+ dayCache = new HashMap<>();
+ byDayAndTime = new HashMap<>();
+ coachesCounter = new HashMap<>();
+
+ for (DayOfWeek day : DayOfWeek.values()) {
+ dayCache.put(day, new ArrayList<>());
+ byDayAndTime.put(day, new HashMap<>());
+ }
+ }
public void addNewTrainingSession(TrainingSession trainingSession) {
- //сохраняем занятие в расписании
+ if (trainingSession == null) {
+ return;
+ }
+
+ DayOfWeek day = trainingSession.getDayOfWeek();
+ TimeOfDay time = trainingSession.getTimeOfDay();
+ Coach coach = trainingSession.getCoach();
+
+ if (day == null || time == null || coach == null) {
+ return;
+ }
+
+ // 1) Добавление в список дня
+ List dayList = dayCache.get(day);
+ dayList.add(trainingSession);
+
+ // сортируем по времени начала (разрешено делать при добавлении)
+ Collections.sort(dayList, new Comparator() {
+ @Override
+ public int compare(TrainingSession a, TrainingSession b) {
+ return a.getTimeOfDay().compareTo(b.getTimeOfDay());
+ }
+ });
+
+ // Добавление в map день->время->список
+ Map> timeMap = byDayAndTime.get(day);
+
+ List sessionsAtTime = timeMap.get(time);
+ if (sessionsAtTime == null) {
+ sessionsAtTime = new ArrayList<>();
+ timeMap.put(time, sessionsAtTime);
+ }
+ sessionsAtTime.add(trainingSession);
+
+ // Сразу обновляем статистику по тренерам
+ Integer count = coachesCounter.get(coach);
+ if (count == null) {
+ coachesCounter.put(coach, 1);
+ } else {
+ coachesCounter.put(coach, count + 1);
+ }
+ }
+
+
+ public List getTrainingSessionsForDay(DayOfWeek dayOfWeek) {
+ if (dayOfWeek == null) {
+ return new ArrayList<>();
+ }
+ return dayCache.get(dayOfWeek);
}
- public /* непонятно, что возвращать */ getTrainingSessionsForDay(DayOfWeek dayOfWeek) {
- //как реализовать, тоже непонятно, но сложность должна быть О(1)
+
+ public List getTrainingSessionsForDayAndTime(DayOfWeek dayOfWeek, TimeOfDay timeOfDay) {
+ if (dayOfWeek == null || timeOfDay == null) {
+ return new ArrayList<>();
+ }
+
+ Map> timeMap = byDayAndTime.get(dayOfWeek);
+ List result = timeMap.get(timeOfDay);
+
+ if (result == null) {
+ return new ArrayList<>();
+ }
+ return result;
}
- public /* непонятно, что возвращать */ getTrainingSessionsForDayAndTime(DayOfWeek dayOfWeek, TimeOfDay timeOfDay) {
- //как реализовать, тоже непонятно, но сложность должна быть О(1)
+ // Теперь без перебора всех тренировок: берём готовую статистику
+ public List getCountByCoaches() {
+ List result = new ArrayList<>();
+
+ for (Coach coach : coachesCounter.keySet()) {
+ result.add(new CounterOfTrainings(coach, coachesCounter.get(coach)));
+ }
+
+ // сортировка по убыванию количества
+ Collections.sort(result, new Comparator() {
+ @Override
+ public int compare(CounterOfTrainings a, CounterOfTrainings b) {
+ return b.getCount() - a.getCount();
+ }
+ });
+
+ return result;
+ }
+
+ public static class CounterOfTrainings {
+ private Coach coach;
+ private int count;
+
+ public CounterOfTrainings(Coach coach, int count) {
+ this.coach = coach;
+ this.count = count;
+ }
+
+ public Coach getCoach() {
+ return coach;
+ }
+
+ public int getCount() {
+ return count;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/test/ru/yandex/practicum/gym/TimetableTest.java b/test/ru/yandex/practicum/gym/TimetableTest.java
index e6c5e39..fd90f48 100644
--- a/test/ru/yandex/practicum/gym/TimetableTest.java
+++ b/test/ru/yandex/practicum/gym/TimetableTest.java
@@ -1,9 +1,10 @@
package ru.yandex.practicum.gym;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import java.util.*;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
public class TimetableTest {
@@ -13,13 +14,20 @@ void testGetTrainingSessionsForDaySingleSession() {
Group group = new Group("Акробатика для детей", Age.CHILD, 60);
Coach coach = new Coach("Васильев", "Николай", "Сергеевич");
- TrainingSession singleTrainingSession = new TrainingSession(group, coach,
- DayOfWeek.MONDAY, new TimeOfDay(13, 0));
+ TrainingSession singleTrainingSession = new TrainingSession(
+ group, coach, DayOfWeek.MONDAY, new TimeOfDay(13, 0)
+ );
timetable.addNewTrainingSession(singleTrainingSession);
- //Проверить, что за понедельник вернулось одно занятие
- //Проверить, что за вторник не вернулось занятий
+ // Проверить, что за понедельник вернулось одно занятие
+ List mondaySessions = timetable.getTrainingSessionsForDay(DayOfWeek.MONDAY);
+ assertEquals(1, mondaySessions.size());
+ assertSame(singleTrainingSession, mondaySessions.get(0));
+
+ // Проверить, что за вторник не вернулось занятий
+ List tuesdaySessions = timetable.getTrainingSessionsForDay(DayOfWeek.TUESDAY);
+ assertTrue(tuesdaySessions.isEmpty());
}
@Test
@@ -29,26 +37,40 @@ void testGetTrainingSessionsForDayMultipleSessions() {
Coach coach = new Coach("Васильев", "Николай", "Сергеевич");
Group groupAdult = new Group("Акробатика для взрослых", Age.ADULT, 90);
- TrainingSession thursdayAdultTrainingSession = new TrainingSession(groupAdult, coach,
- DayOfWeek.THURSDAY, new TimeOfDay(20, 0));
-
+ TrainingSession thursdayAdultTrainingSession = new TrainingSession(
+ groupAdult, coach, DayOfWeek.THURSDAY, new TimeOfDay(20, 0)
+ );
timetable.addNewTrainingSession(thursdayAdultTrainingSession);
Group groupChild = new Group("Акробатика для детей", Age.CHILD, 60);
- TrainingSession mondayChildTrainingSession = new TrainingSession(groupChild, coach,
- DayOfWeek.MONDAY, new TimeOfDay(13, 0));
- TrainingSession thursdayChildTrainingSession = new TrainingSession(groupChild, coach,
- DayOfWeek.THURSDAY, new TimeOfDay(13, 0));
- TrainingSession saturdayChildTrainingSession = new TrainingSession(groupChild, coach,
- DayOfWeek.SATURDAY, new TimeOfDay(10, 0));
+ TrainingSession mondayChildTrainingSession = new TrainingSession(
+ groupChild, coach, DayOfWeek.MONDAY, new TimeOfDay(13, 0)
+ );
+ TrainingSession thursdayChildTrainingSession = new TrainingSession(
+ groupChild, coach, DayOfWeek.THURSDAY, new TimeOfDay(13, 0)
+ );
+ TrainingSession saturdayChildTrainingSession = new TrainingSession(
+ groupChild, coach, DayOfWeek.SATURDAY, new TimeOfDay(10, 0)
+ );
timetable.addNewTrainingSession(mondayChildTrainingSession);
timetable.addNewTrainingSession(thursdayChildTrainingSession);
timetable.addNewTrainingSession(saturdayChildTrainingSession);
// Проверить, что за понедельник вернулось одно занятие
+ List mondaySessions = timetable.getTrainingSessionsForDay(DayOfWeek.MONDAY);
+ assertEquals(1, mondaySessions.size());
+ assertSame(mondayChildTrainingSession, mondaySessions.get(0));
+
// Проверить, что за четверг вернулось два занятия в правильном порядке: сначала в 13:00, потом в 20:00
+ List thursdaySessions = timetable.getTrainingSessionsForDay(DayOfWeek.THURSDAY);
+ assertEquals(2, thursdaySessions.size());
+ assertSame(thursdayChildTrainingSession, thursdaySessions.get(0)); // 13:00
+ assertSame(thursdayAdultTrainingSession, thursdaySessions.get(1)); // 20:00
+
// Проверить, что за вторник не вернулось занятий
+ List tuesdaySessions = timetable.getTrainingSessionsForDay(DayOfWeek.TUESDAY);
+ assertTrue(tuesdaySessions.isEmpty());
}
@Test
@@ -57,13 +79,80 @@ void testGetTrainingSessionsForDayAndTime() {
Group group = new Group("Акробатика для детей", Age.CHILD, 60);
Coach coach = new Coach("Васильев", "Николай", "Сергеевич");
- TrainingSession singleTrainingSession = new TrainingSession(group, coach,
- DayOfWeek.MONDAY, new TimeOfDay(13, 0));
+ TrainingSession singleTrainingSession = new TrainingSession(
+ group, coach, DayOfWeek.MONDAY, new TimeOfDay(13, 0)
+ );
timetable.addNewTrainingSession(singleTrainingSession);
- //Проверить, что за понедельник в 13:00 вернулось одно занятие
- //Проверить, что за понедельник в 14:00 не вернулось занятий
+ // Проверить, что за понедельник в 13:00 вернулось одно занятие
+ List at13 = timetable.getTrainingSessionsForDayAndTime(
+ DayOfWeek.MONDAY, new TimeOfDay(13, 0)
+ );
+ assertEquals(1, at13.size());
+ assertSame(singleTrainingSession, at13.get(0));
+
+ // Проверить, что за понедельник в 14:00 не вернулось занятий
+ List at14 = timetable.getTrainingSessionsForDayAndTime(
+ DayOfWeek.MONDAY, new TimeOfDay(14, 0)
+ );
+ assertTrue(at14.isEmpty());
+ }
+
+ // -------------------- 3+ теста для getCountByCoaches() --------------------
+
+ @Test
+ void testGetCountByCoaches_emptyTimetable_returnsEmptyList() {
+ Timetable timetable = new Timetable();
+
+ List result = timetable.getCountByCoaches();
+
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ void testGetCountByCoaches_singleCoach_multipleTrainings_correctCount() {
+ Timetable timetable = new Timetable();
+
+ Coach coach = new Coach("Иванов", "Иван", "Иванович");
+ Group group = new Group("Группа", Age.ADULT, 60);
+
+ timetable.addNewTrainingSession(new TrainingSession(group, coach, DayOfWeek.MONDAY, new TimeOfDay(10, 0)));
+ timetable.addNewTrainingSession(new TrainingSession(group, coach, DayOfWeek.TUESDAY, new TimeOfDay(10, 0)));
+ timetable.addNewTrainingSession(new TrainingSession(group, coach, DayOfWeek.WEDNESDAY, new TimeOfDay(10, 0)));
+
+ List result = timetable.getCountByCoaches();
+
+ assertEquals(1, result.size());
+ assertEquals(coach, result.get(0).getCoach());
+ assertEquals(3, result.get(0).getCount());
}
-}
+ @Test
+ void testGetCountByCoaches_twoCoaches_sortedByCountDesc() {
+ Timetable timetable = new Timetable();
+
+ Coach coachMore = new Coach("Петров", "Пётр", "Петрович");
+ Coach coachLess = new Coach("Сидоров", "Сидор", "Сидорович");
+ Group group = new Group("Группа", Age.ADULT, 60);
+
+ // coachMore = 3 занятия
+ timetable.addNewTrainingSession(new TrainingSession(group, coachMore, DayOfWeek.MONDAY, new TimeOfDay(10, 0)));
+ timetable.addNewTrainingSession(new TrainingSession(group, coachMore, DayOfWeek.TUESDAY, new TimeOfDay(10, 0)));
+ timetable.addNewTrainingSession(new TrainingSession(group, coachMore, DayOfWeek.WEDNESDAY, new TimeOfDay(10, 0)));
+
+ // coachLess = 1 занятие
+ timetable.addNewTrainingSession(new TrainingSession(group, coachLess, DayOfWeek.THURSDAY, new TimeOfDay(10, 0)));
+
+ List result = timetable.getCountByCoaches();
+
+ assertEquals(2, result.size());
+
+ assertEquals(coachMore, result.get(0).getCoach());
+ assertEquals(3, result.get(0).getCount());
+
+ assertEquals(coachLess, result.get(1).getCoach());
+ assertEquals(1, result.get(1).getCount());
+ }
+}
\ No newline at end of file