Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 36 additions & 22 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
# Игнорируем всё содержимое .idea — это папка настроек среды разработки
# Оставляем только нужные файлы, чтобы IDE могла корректно открыть проект
.idea/
!.idea/misc.xml # Уровень JDK, базовые настройки проекта
!.idea/modules.xml # Структура модулей (если нет Maven/Gradle)
!.idea/libraries/ # Подключённые библиотеки, например JUnit
!.idea/vcs.xml # Настройки системы контроля версий (Git)

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
# Игнорируем файлы модулей IntelliJ (.iml) — не нужны в репозитории
*.iml

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### Build output ###
# Исключаем папки, которые содержат скомпилированные классы и артефакты
out/ # Папка вывода сборки IntelliJ
bin/ # Папка вывода Eclipse/ручной сборки
target/ # Папка сборки Maven (если появится)

### OS ###
# Системные файлы macOS, не должны попадать в репозиторий
.DS_Store

### VS Code ###
# Конфигурации Visual Studio Code (если кто-то откроет проект там)
.vscode/

### Mac OS ###
.DS_Store
### Eclipse ###
# Игнорируем все файлы и папки, связанные с Eclipse IDE
.apt_generated # Автоматически сгенерированные исходники
.classpath # Файл конфигурации путей классов
.factorypath # Конфигурация аннотаций
.project # Основной файл проекта Eclipse
.settings # Папка с настройками проекта
.springBeans # Конфиги Spring Beans (если используется)
.sts4-cache # Кэш Spring Tool Suite (STS)

### NetBeans ###
# Всё, что создаёт NetBeans IDE
nbproject/private/ # Личные настройки проекта
nbbuild/ # Папка сборки NetBeans
dist/ # Артефакты сборки (JAR и т.д.)
nbdist/ # Расширенная папка вывода
.nb-gradle/ # Кэш Gradle от NetBeans
10 changes: 0 additions & 10 deletions .idea/.gitignore

This file was deleted.

12 changes: 0 additions & 12 deletions java-sprint4-hw.iml

This file was deleted.

9 changes: 5 additions & 4 deletions src/manager/HistoryManager.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package manager;
//Интерфейс менеджера истории просмотров задач.

import model.Task;
import java.util.List;

public interface HistoryManager {
void add(Task task);
List<Task> getHistory();
}
void add(Task task); // записать просмотр
void remove(int id); // удалить по id (нужно при удалении задач)
List<Task> getHistory();// вернуть историю в порядке просмотра
}
97 changes: 87 additions & 10 deletions src/manager/InMemoryHistoryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,99 @@

import model.Task;
import java.util.*;
//Хранит максимум 10 последних задач. При превышении лимита
// самая старая задача удаляется.

/** HistoryManager на базе двусвязного списка + HashMap<id, node> */
public class InMemoryHistoryManager implements HistoryManager {
private static final int MAX_HISTORY = 10;
private final Deque<Task> history = new ArrayDeque<>();

/* ───── узел списка ───── */
private static class Node {
Task data;
Node prev;
Node next;

Node(Node prev, Task data, Node next) {
this.prev = prev;
this.data = data;
this.next = next;
}
}

/* ───── поля ───── */
private final Map<Integer, Node> index = new HashMap<>();
private Node head;
private Node tail;

/* ───── вспомогательные ───── */

/** добавляем просмотр в хвост */
private void linkLast(Task task) {
Node oldTail = tail;
Node newNode = new Node(oldTail, task, null); // n → newNode
tail = newNode;

if (oldTail == null) {
head = newNode; // фигурные скобки
} else {
oldTail.next = newNode; // фигурные скобки
}
}

/** удаляем произвольный узел */
private void removeNode(Node target) {
if (target == null) {
return;
}

Node prev = target.prev;
Node next = target.next;

if (prev != null) {
prev.next = next;
} else {
head = next; // фигурные скобки
}

if (next != null) {
next.prev = prev;
} else {
tail = prev; // фигурные скобки
}
}

/** выгружаем историю списком */
private List<Task> getTasks() {
List<Task> list = new ArrayList<>();
for (Node current = head; current != null; current = current.next) {
list.add(current.data);
}
return list;
}

/* ───── HistoryManager API ───── */

@Override
public void add(Task task) {
history.addLast(task);
if (history.size() > MAX_HISTORY) {
history.pollFirst();
if (task == null) {
return; // фигурные скобки
}

/* если id уже есть — убираем старый узел */
Node duplicate = index.remove(task.getId());
removeNode(duplicate);

/* вносим новый просмотр */
linkLast(task);
index.put(task.getId(), tail);
}
//Возвращает список просмотренных задач (в порядке просмотра).

@Override
public void remove(int id) {
Node node = index.remove(id);
removeNode(node);
}

@Override
public List<Task> getHistory() {
return new ArrayList<>(history);
return getTasks();
}
}
}
100 changes: 33 additions & 67 deletions src/manager/InMemoryTaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
import model.*;
import java.util.*;

// InMemoryTaskManager — реализация интерфейса TaskManager,
// хранящая задачи, эпики и подзадачи в оперативной памяти.
// Поддерживает создание, обновление, удаление и получение задач всех типов,
// а также отслеживает историю просмотров через HistoryManager.
// InMemoryTaskManager хранит задачи, эпики и подзадачи в памяти
// + ведёт историю просмотров через HistoryManager.
public class InMemoryTaskManager implements TaskManager {
private final Map<Integer, Task> tasks = new HashMap<>();
private final Map<Integer, Epic> epics = new HashMap<>();

/* ---------- хранилища ---------- */
private final Map<Integer, Task> tasks = new HashMap<>();
private final Map<Integer, Epic> epics = new HashMap<>();
private final Map<Integer, Subtask> subtasks = new HashMap<>();

/* ---------- менеджер истории ---------- */
private final HistoryManager historyManager = Managers.getDefaultHistory();
private int nextId = 1;

private int generateId() {
return nextId++;
}
private int nextId = 1;
private int generateId() { return nextId++; }

/* ---------- создание ---------- */
@Override
public int addNewTask(Task task) {
task.setId(generateId());
Expand All @@ -35,49 +36,37 @@ public int addNewEpic(Epic epic) {
@Override
public int addNewSubtask(Subtask subtask) {
Epic epic = epics.get(subtask.getEpicId());
if (epic == null) {
throw new IllegalArgumentException("Эпик не найден");
}
if (epic == null) throw new IllegalArgumentException("Эпик не найден");

int id = generateId();
subtask.setId(id);
subtasks.put(id, subtask);
epic.addSubtaskId(id);
return id;
}

@Override
public void updateTask(Task task) {
if (tasks.containsKey(task.getId())) {
tasks.put(task.getId(), task);
}
}

@Override
public void updateEpic(Epic epic) {
if (epics.containsKey(epic.getId())) {
epics.put(epic.getId(), epic);
}
}

@Override
public void updateSubtask(Subtask subtask) {
if (subtasks.containsKey(subtask.getId())) {
subtasks.put(subtask.getId(), subtask);
}
}
/* ---------- обновление ---------- */
@Override public void updateTask(Task task) { if (tasks.containsKey(task.getId())) tasks.put(task.getId(), task); }
@Override public void updateEpic(Epic epic) { if (epics.containsKey(epic.getId())) epics.put(epic.getId(), epic); }
@Override public void updateSubtask(Subtask s) { if (subtasks.containsKey(s.getId())) subtasks.put(s.getId(), s); }

/* ---------- удаление ---------- */
@Override
public void removeTask(int id) {
tasks.remove(id);
historyManager.remove(id); // добавил удаляем из истории
}

@Override
public void removeEpic(int id) {
Epic epic = epics.remove(id);
if (epic != null) {
// удаляем все подзадачи эпика
for (int subId : epic.getSubtaskIds()) {
subtasks.remove(subId);
historyManager.remove(subId); // добавил подзадача из истории
}
historyManager.remove(id); // добавил сам эпик из истории
}
}

Expand All @@ -86,47 +75,23 @@ public void removeSubtask(int id) {
Subtask subtask = subtasks.remove(id);
if (subtask != null) {
Epic epic = epics.get(subtask.getEpicId());
if (epic != null) {
epic.getSubtaskIds().remove((Integer) id);
}
if (epic != null) epic.getSubtaskIds().remove((Integer) id);
}
historyManager.remove(id); // добавил subtask из истории
}

/* ---------- получение + запись в историю ---------- */
@Override
public Task getTask(int id) {
Task t = tasks.get(id);
if (t != null) historyManager.add(t);
return t;
}

@Override
public Epic getEpic(int id) {
Epic e = epics.get(id);
if (e != null) historyManager.add(e);
return e;
}

@Override
public Subtask getSubtask(int id) {
Subtask s = subtasks.get(id);
if (s != null) historyManager.add(s);
return s;
}

public Task getTask(int id) { Task t = tasks.get(id); if (t != null) historyManager.add(t); return t; }
@Override
public List<Task> getTasks() {
return new ArrayList<>(tasks.values());
}

public Epic getEpic(int id) { Epic e = epics.get(id); if (e != null) historyManager.add(e); return e; }
@Override
public List<Epic> getEpics() {
return new ArrayList<>(epics.values());
}
public Subtask getSubtask(int id) { Subtask s = subtasks.get(id); if (s != null) historyManager.add(s); return s; }

@Override
public List<Subtask> getSubtasks() {
return new ArrayList<>(subtasks.values());
}
/* ---------- списки ---------- */
@Override public List<Task> getTasks() { return new ArrayList<>(tasks.values()); }
@Override public List<Epic> getEpics() { return new ArrayList<>(epics.values()); }
@Override public List<Subtask> getSubtasks() { return new ArrayList<>(subtasks.values()); }

@Override
public List<Subtask> getEpicSubtasks(int epicId) {
Expand All @@ -141,6 +106,7 @@ public List<Subtask> getEpicSubtasks(int epicId) {
return result;
}

/* ---------- история ---------- */
@Override
public List<Task> getHistory() {
return historyManager.getHistory();
Expand Down
Loading