diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000..94f04f1
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,19 @@
+
+
+
+ 10.25.0
+ Everything
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/checkstyleidea-libs/readme.txt b/.idea/checkstyleidea-libs/readme.txt
new file mode 100644
index 0000000..d011e75
--- /dev/null
+++ b/.idea/checkstyleidea-libs/readme.txt
@@ -0,0 +1,6 @@
+This folder contains libraries copied from the "java-kanban" project.
+It is managed by the CheckStyle-IDEA IDE plugin.
+Do not modify this folder while the IDE is running.
+When the IDE is stopped, you may delete this folder at any time. It will be recreated as needed.
+In order to prevent the CheckStyle-IDEA IDE plugin from creating this folder,
+uncheck the "Copy libraries from project directory" option in the CheckStyle-IDEA settings dialog.
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..87bb112
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java-kanban.iml b/java-kanban.iml
index 5dfd50f..265bb5c 100644
--- a/java-kanban.iml
+++ b/java-kanban.iml
@@ -1,5 +1,8 @@
+
+
+
diff --git a/src/Main.java b/src/Main.java
index 039c654..784c22a 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -8,86 +8,72 @@
public class Main {
public static void main(String[] args) {
-
TaskManager taskManager = Managers.getDefault();
-
- // 1.Создать таску
+ // 1. Создать таску
System.out.println("Создать таску");
- Task taskForCreate = new Task("Name", "Desc", TaskStatus.NEW);
- taskManager.createTask(taskForCreate);
+ Task task = new Task("Name", "Desc", TaskStatus.NEW);
+ taskManager.createTask(task);
System.out.println(taskManager.getTasks());
+ System.out.println("История после создания задачи (должна быть пустая): " + taskManager.getHistory());
System.out.println();
- // 2.Получить таску
+ // 2. Получить таску (добавится в историю)
System.out.println("Получить таску");
- System.out.println(taskManager.getTask(taskForCreate.getId()));
+ System.out.println(taskManager.getTask(task.getId()));
+ System.out.println("История после первого просмотра (1 задача): " + taskManager.getHistory());
System.out.println();
- // 3. Проверим обновление
- System.out.println("Проверим обновление");
- Task taskForUpdate = new Task(taskForCreate.getId(), "New name",
- taskForCreate.getDescription(), TaskStatus.IN_PROGRESS);
- taskForUpdate = taskManager.updateTask(taskForUpdate);
- System.out.println(taskManager.getTasks());
- System.out.println();
-
- //4. Удаляем таску
- System.out.println("Удаляем таску");
- taskManager.deleteTask(taskForUpdate.getId());
- System.out.println(taskManager.getTasks());
+ // 3. Получить таску еще раз (должна остаться одна запись)
+ System.out.println("Получить таску повторно");
+ System.out.println(taskManager.getTask(task.getId()));
+ System.out.println("История после повторного просмотра (все равно 1 задача): " + taskManager.getHistory());
System.out.println();
- //5. Создаём Эпик
+ // 4. Создаём Эпик
System.out.println("Создаём Эпик");
Epic epic = new Epic("Отпуск", "Организовать отпуск");
taskManager.createEpic(epic);
+ System.out.println("История после создания эпика (не должна измениться): " + taskManager.getHistory());
+ System.out.println();
+
+ // 5. Просматриваем эпик (добавится в историю)
+ System.out.println("Просматриваем эпик");
System.out.println(taskManager.getEpic(epic.getId()));
+ System.out.println("История после просмотра эпика (2 задачи): " + taskManager.getHistory());
System.out.println();
- //5. Создаём Сабтаски
+ // 6. Создаём Сабтаски
System.out.println("Создаём Сабтаски");
Subtask subtask1 = new Subtask("Путёвка", "Выбрать путёвку", TaskStatus.NEW, epic.getId());
Subtask subtask2 = new Subtask("Билеты", "Купить билеты", TaskStatus.NEW, epic.getId());
taskManager.createSubtask(subtask1);
taskManager.createSubtask(subtask2);
- taskManager.getEpicSubtasks(epic.getId());
- System.out.println(taskManager.getEpicSubtasks(epic.getId()));
- System.out.println();
-
- //6. Проверяем статус Эпика (NEW)
- System.out.println("Проверяем статус Эпика " + taskManager.getEpic(epic.getId()).getTaskStatus());
+ System.out.println("История после создания подзадач (не должна измениться): " + taskManager.getHistory());
System.out.println();
- //7. Меняем статус первого Сабтаска.
- Subtask updatedSubtask = new Subtask(subtask1.getId(), subtask1.getName(), subtask1.getDescription(),
- TaskStatus.DONE, subtask1.getEpicId());
- taskManager.updateSubtask(updatedSubtask);
- System.out.println("Статус Эпика после изменения одной Сабтаски " + taskManager.getEpic(epic.getId()).getTaskStatus());
+ // 7. Просматриваем подзадачи (добавляются в историю)
+ System.out.println("Просматриваем подзадачи");
+ System.out.println("Подзадача 1: " + taskManager.getSubtasks(subtask1.getId()));
+ System.out.println("Текущая история (3 задачи - задача, эпик, подзадача1): " + taskManager.getHistory());
+ System.out.println("Подзадача 2: " + taskManager.getSubtasks(subtask2.getId()));
+ System.out.println("История после просмотра второй подзадачи (4 задачи): " + taskManager.getHistory());
System.out.println();
- //8. Меняем статус второго Сабтаска.
- Subtask updatedSubtask2 = new Subtask(subtask2.getId(), subtask2.getName(), subtask2.getDescription(),
- TaskStatus.DONE, subtask2.getEpicId());
- taskManager.updateSubtask(updatedSubtask2);
- System.out.println("Статус Эпика после изменения одной Сабтаски " + taskManager.getEpic(epic.getId()).getTaskStatus());
+ // 8. Удаляем таску (должна удалиться из истории)
+ System.out.println("Удаляем таску");
+ taskManager.deleteTask(task.getId());
+ System.out.println("История после удаления задачи (3 задачи): " + taskManager.getHistory());
System.out.println();
- //9. Удаляем Эпик.
+ // 9. Удаляем Эпик (должны удалиться эпик и его подзадачи из истории)
+ System.out.println("Удаляем Эпик");
taskManager.deleteEpic(epic.getId());
- System.out.println("Эпики после удаления: " + taskManager.getEpics());
- System.out.println("Сабтаски после удаления Эпика: " + taskManager.getSubtasks());
+ System.out.println("История после удаления эпика (должна быть пустая): " + taskManager.getHistory());
System.out.println();
- //10. Проверяем удаление всех задач.
- taskManager.deleteAllTasks();
- System.out.println("Все Таски после очистки: " + taskManager.getTasks());
- System.out.println("Все Сабтаски после очистки: " + taskManager.getSubtasks());
- System.out.println("Все Эпики после очистки: " + taskManager.getEpics());
-
- //11.Проверяем историю.
- System.out.println("Проверяем историю.");
- System.out.println(taskManager.getHistory());
- System.out.println();
+ // 10. Проверяем историю после всех операций
+ System.out.println("Финальная проверка истории");
+ System.out.println("История: " + taskManager.getHistory());
}
}
diff --git a/src/manager/HistoryManager.java b/src/manager/HistoryManager.java
index 3307c60..be0776e 100644
--- a/src/manager/HistoryManager.java
+++ b/src/manager/HistoryManager.java
@@ -8,4 +8,7 @@ public interface HistoryManager {
List getHistory();
void add(Task task);
+
+ void remove(int id);
+
}
diff --git a/src/manager/InMemoryHistoryManager.java b/src/manager/InMemoryHistoryManager.java
index e47e982..3ec8caa 100644
--- a/src/manager/InMemoryHistoryManager.java
+++ b/src/manager/InMemoryHistoryManager.java
@@ -1,31 +1,86 @@
package manager;
import tasks.Task;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
public class InMemoryHistoryManager implements HistoryManager {
- private static final int MAX_HISTORY_SIZE = 10;
- private final LinkedList history = new LinkedList<>();
- @Override
- public List getHistory() {
- //Получить список историй.
- return new LinkedList<>(history);
- }
+ private final Map nodeMap = new HashMap<>();
+ private Node head;
+ private Node tail;
+ // Добавление задачи в историю просмотров.
@Override
public void add(Task task) {
- //Добавить таску в список с историей.
if (task == null) {
return;
}
- if (history.size() >= MAX_HISTORY_SIZE) {
- history.removeFirst();
+ remove(task.getId());
+
+ Node node = new Node(task);
+ linkLast(node);
+ nodeMap.put(task.getId(), node);
+ }
+
+ // Удаление задачи из истории по ID.
+ @Override
+ public void remove(int id) {
+ Node node = nodeMap.remove(id);
+
+ if (node != null) {
+ removeNode(node);
+ }
+ }
+
+ // Получение списка задач из истории просмотров.
+ @Override
+ public List getHistory() {
+ List history = new ArrayList<>();
+
+ Node current = head;
+ while (current != null) {
+ history.add(current.item);
+ current = current.next;
+ }
+ return history;
+ }
+
+ // Добавление узла в конец двусвязного списка.
+ private void linkLast(Node node) {
+ if (tail == null) {
+ head = tail = node;
+ } else {
+ tail.next = node;
+ node.prev = tail;
+ tail = node;
+ }
+ }
+
+ // Удаление узла из двусвязного списка
+ private void removeNode(Node node) {
+ if (node.prev != null) {
+ node.prev.next = node.next;
+ } else {
+ head = node.next;
}
- history.remove(task);
- history.addLast(task);
+ if (node.next != null) {
+ node.next.prev = node.prev;
+ } else {
+ tail = node.prev;
+ }
+ }
+
+ // Внутренний класс для узла двусвязного списка.
+ private static class Node {
+ T item;
+ Node prev;
+ Node next;
+
+ Node(T item) {
+ this.item = item;
+ }
}
}
+
diff --git a/src/manager/InMemoryTaskManager.java b/src/manager/InMemoryTaskManager.java
index e755b7d..2c7dae9 100644
--- a/src/manager/InMemoryTaskManager.java
+++ b/src/manager/InMemoryTaskManager.java
@@ -23,6 +23,7 @@ public class InMemoryTaskManager implements TaskManager {
// Методы для Task
@Override
public List getTasks() {
+
return new ArrayList<>(tasks.values());
}
@@ -54,7 +55,11 @@ public Task updateTask(Task task) {
@Override
public Task deleteTask(int id) {
- return tasks.remove(id);
+ Task task = tasks.remove(id);
+ if (task != null) {
+ historyManager.remove(id);
+ }
+ return task;
}
// Методы для Subtask
@@ -119,6 +124,7 @@ public Subtask deleteSubtask(int id) {
epic.removeSubtaskId(id);
updateEpicStatus(epic);
}
+ historyManager.remove(id);
}
return subtask;
}
@@ -162,8 +168,9 @@ public Epic deleteEpic(int id) {
if (epic != null) {
for (Integer subtaskId : epic.getSubtasksId()) {
subtasks.remove(subtaskId);
+ historyManager.remove(subtaskId);
}
-
+ historyManager.remove(id);
}
return epic;
}
@@ -186,9 +193,38 @@ public List getEpicSubtasks(int epicId) {
@Override
public void deleteAllTasks() {
+ for (Integer taskId : tasks.keySet()) {
+ historyManager.remove(taskId);
+ }
tasks.clear();
+ }
+
+ @Override
+ public void deleteAllSubtasks() {
+ for (Integer subtaskId : subtasks.keySet()) {
+ historyManager.remove(subtaskId);
+ }
subtasks.clear();
+ for (Epic epic : epics.values()) {
+ epic.getSubtasksId().clear();
+ updateEpicStatus(epic);
+ }
+ }
+
+ @Override
+ public void deleteAllEpics() {
+ deleteAllSubtasks();
+ for (Integer epicId : epics.keySet()) {
+ historyManager.remove(epicId);
+ }
epics.clear();
+ }
+
+ @Override
+ public void deleteAll() {
+ deleteAllTasks();
+ deleteAllSubtasks();
+ deleteAllEpics();
generatorId = 1;
}
diff --git a/src/manager/TaskManager.java b/src/manager/TaskManager.java
index e714b04..81e0619 100644
--- a/src/manager/TaskManager.java
+++ b/src/manager/TaskManager.java
@@ -41,7 +41,15 @@ public interface TaskManager {
List getEpicSubtasks(int epicId);
+ // Метод для получения истории
+ List getHistory();
+
+ // Методы для удаления
void deleteAllTasks();
- List getHistory();
+ void deleteAllSubtasks();
+
+ void deleteAllEpics();
+
+ void deleteAll();
}
diff --git a/test/manager/InMemoryHistoryManagerTest.java b/test/manager/InMemoryHistoryManagerTest.java
index a08e241..d5e7059 100644
--- a/test/manager/InMemoryHistoryManagerTest.java
+++ b/test/manager/InMemoryHistoryManagerTest.java
@@ -6,8 +6,7 @@
import tasks.TaskStatus;
import java.util.List;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.*;
public class InMemoryHistoryManagerTest {
@@ -46,5 +45,39 @@ void addToHistory() {
assertEquals(1, history.size(), "История должна содержать 1 задачу");
assertEquals(task, history.get(0), "Задача в истории должна соответствовать добавленной");
}
+
+ // Повторное добавление задачи заменяет предыдущую запись.
+ @Test
+ void duplicateTaskInHistory() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ historyManager.add(task);
+ Task updatedTask = new Task(task.getId(), "Task", "Updated Desc", TaskStatus.IN_PROGRESS);
+ historyManager.add(updatedTask);
+
+ List history = historyManager.getHistory();
+ assertEquals(1, history.size(), "История должна содержать только одну задачу");
+ assertEquals(TaskStatus.IN_PROGRESS, history.get(0).getTaskStatus(), "Задача должна быть обновлена");
+ }
+
+ // Удаление задачи из истории.
+ @Test
+ void removeTaskFromHistory() {
+ Task task1 = taskManager.createTask(new Task("Task1", "Desc", TaskStatus.NEW));
+ Task task2 = taskManager.createTask(new Task("Task2", "Desc", TaskStatus.IN_PROGRESS));
+ historyManager.add(task1);
+ historyManager.add(task2);
+ historyManager.remove(task1.getId());
+
+ List history = historyManager.getHistory();
+ assertEquals(1, history.size(), "История должна содержать 1 задачу после удаления");
+ assertEquals(task2, history.get(0), "Оставшаяся задача должна быть task2");
+ }
+
+ // Пустая история.
+ @Test
+ void emptyHistory() {
+ List history = historyManager.getHistory();
+ assertTrue(history.isEmpty(), "История должна быть пустой");
+ }
}
diff --git a/test/manager/InMemoryTaskManagerTest.java b/test/manager/InMemoryTaskManagerTest.java
index e9359fe..1af39da 100644
--- a/test/manager/InMemoryTaskManagerTest.java
+++ b/test/manager/InMemoryTaskManagerTest.java
@@ -126,4 +126,87 @@ void taskRemainsUnchanged() {
assertEquals(original.getTaskStatus(), added.getTaskStatus(), "Статус не должен изменяться");
}
+ // Удаление задачи удаляет её из истории.
+ @Test
+ void deleteTaskRemovesFromHistory() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ taskManager.getTask(task.getId());
+ taskManager.deleteTask(task.getId());
+
+ List history = taskManager.getHistory();
+ assertTrue(history.isEmpty(), "История должна быть пустой после удаления задачи");
+ }
+
+ // Удаление эпика удаляет его подзадачи из истории.
+ @Test
+ void deleteEpicRemovesSubtasksFromHistory() {
+ Epic epic = taskManager.createEpic(new Epic("Epic", "Desc"));
+ Subtask subtask = taskManager.createSubtask(
+ new Subtask("Subtask", "Desc", TaskStatus.NEW, epic.getId()));
+ taskManager.getSubtasks(subtask.getId());
+ taskManager.getEpic(epic.getId());
+ taskManager.deleteEpic(epic.getId());
+
+ List history = taskManager.getHistory();
+ assertTrue(history.isEmpty(), "История должна быть пустой после удаления эпика");
+ }
+
+ // Удаляем только таски.
+ @Test
+ void deleteAllTasksRemovesOnlyTasks() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ Epic epic = taskManager.createEpic(new Epic("Epic", "Desc"));
+ Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId()));
+
+ taskManager.deleteAllTasks();
+
+ assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены");
+ assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться");
+ assertFalse(taskManager.getSubtasks().isEmpty(), "Подзадачи должны остаться");
+ }
+
+ // Удаляем только сабтаски.
+ @Test
+ void deleteAllSubtasksRemovesOnlySubtasks() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ Epic epic = taskManager.createEpic(new Epic("Epic", "Desc"));
+ Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId()));
+
+ taskManager.deleteAllSubtasks();
+
+ assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться");
+ assertFalse(taskManager.getEpics().isEmpty(), "Эпики должны остаться");
+ assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены");
+ }
+
+ // Удаляем эпики и их сабтаски.
+ @Test
+ void deleteAllEpicsRemovesEpicsAndSubtasks() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ Epic epic = taskManager.createEpic(new Epic("Epic", "Desc"));
+ Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId()));
+
+ taskManager.deleteAllEpics();
+
+ assertFalse(taskManager.getTasks().isEmpty(), "Задачи должны остаться");
+ assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены");
+ assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены");
+ }
+
+ // Удаляем всё.
+ @Test
+ void deleteAllRemovesEverything() {
+ Task task = taskManager.createTask(new Task("Task", "Desc", TaskStatus.NEW));
+ Epic epic = taskManager.createEpic(new Epic("Epic", "Desc"));
+ Subtask subtask = taskManager.createSubtask(new Subtask("Sub", "Desc", TaskStatus.NEW, epic.getId()));
+
+ taskManager.deleteAll();
+
+ assertTrue(taskManager.getTasks().isEmpty(), "Все задачи должны быть удалены");
+ assertTrue(taskManager.getEpics().isEmpty(), "Все эпики должны быть удалены");
+ assertTrue(taskManager.getSubtasks().isEmpty(), "Все подзадачи должны быть удалены");
+ }
}
+
+
+