Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
93a4e37
Добавил новые поля duration, startTime, endTime в класс Task
zephyr0021 Feb 3, 2025
8bd6373
Добавил новые поля в subtask, поправил ошибки, поправил тесты
zephyr0021 Feb 4, 2025
35a6e17
Обновил все конструкторы в тасках, так же обновил хэдеры для файла в …
zephyr0021 Feb 4, 2025
c74fb19
Поправил тесты в соотвествии с изменениями
zephyr0021 Feb 5, 2025
8d8bda0
Поправил ошибки в конструкторах (не надо было удалять старые)
zephyr0021 Feb 5, 2025
a1e1992
Поправил ошибки + тесты, переделал десериализацию
zephyr0021 Feb 6, 2025
c424d64
Добавил обновление полей duration startTime endTime в Epic, поправил …
zephyr0021 Feb 6, 2025
8cd6f43
Написал методы для получения приоритезированных списков задач
zephyr0021 Feb 6, 2025
a080a08
Написал метод для проверки пересечений + обновил тесты
zephyr0021 Feb 10, 2025
f43dcb1
Написал метод для проверки пересечений + обновил тесты
zephyr0021 Feb 10, 2025
8d81768
Дописал тесты на новый код
zephyr0021 Feb 10, 2025
00b1866
Поменял циклы на стримы / лямбды где следует
zephyr0021 Feb 11, 2025
add6b5b
fix codeStyle
zephyr0021 Feb 11, 2025
723de89
fix codeStyle
zephyr0021 Feb 11, 2025
4a423fd
fix codeStyle
zephyr0021 Feb 11, 2025
0d942ce
Поправил ошибки после ревью + обновил тесты и добавил новые
zephyr0021 Feb 13, 2025
574239c
Сделаны правки по ревью
zephyr0021 Feb 14, 2025
e4b581c
Написал новые тесты после правок по ревью
zephyr0021 Feb 14, 2025
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
409 changes: 210 additions & 199 deletions src/Main.java

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/managers/FileBackedTaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ public static FileBackedTaskManager loadFromFile(File file) throws ManagerLoadFr
try (BufferedReader buffer = new BufferedReader(new FileReader(file))) {
FileBackedTaskManager manager = new FileBackedTaskManager();
ArrayList<String> tasks = new ArrayList<>(buffer.lines().toList());
String header = "id,type,name,status,description,epic";
String header = "id,type,name,status,description,epic,duration,start_time,end_time";
tasks.remove(header);
for (String task : tasks) {
tasks.forEach(task -> {
String[] taskInfo = task.split(",");
switch (TaskType.valueOf(taskInfo[1])) {
case TaskType.TASK:
Expand All @@ -122,7 +122,7 @@ public static FileBackedTaskManager loadFromFile(File file) throws ManagerLoadFr
default:
System.out.println("Не определена задача в файле");
}
}
});
return manager;
} catch (IOException e) {
throw new ManagerLoadFromFileException("Возникла ошибка при загрузке данных из файла", file);
Expand All @@ -132,7 +132,7 @@ public static FileBackedTaskManager loadFromFile(File file) throws ManagerLoadFr

private void save() throws ManagerSaveException {
try (FileWriter writer = new FileWriter(managerFile)) {
String header = "id,type,name,status,description,epic\n";
String header = "id,type,name,status,description,epic,duration,start_time,end_time\n";
writer.write(header);
for (Task task : getTasks()) {
writer.write(String.format("%s\n", task.toString()));
Expand Down
106 changes: 76 additions & 30 deletions src/managers/InMemoryTaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@
import tasks.*;
import util.Managers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

public class InMemoryTaskManager implements TaskManager {
private final HashMap<Integer, Task> tasks = new HashMap<>();
private final HashMap<Integer, Subtask> subtasks = new HashMap<>();
private final HashMap<Integer, Epic> epics = new HashMap<>();
private final HistoryManager historyManager = Managers.getDefaultHistory();
private int taskId = 0;
private final Comparator<Task> comparator = Comparator.comparing(Task::getStartTime,
Comparator.nullsLast(Comparator.naturalOrder()));
private final TreeSet<Task> prioritizedTasks = new TreeSet<>(comparator);

@Override
public ArrayList<Task> getTasks() {
Expand Down Expand Up @@ -54,12 +58,8 @@ public Epic getEpic(int id) {
@Override
public ArrayList<Subtask> getEpicSubtasks(int epicId) {
Epic epic = epics.get(epicId);
ArrayList<Subtask> epicSubtasks = new ArrayList<>();
if (epic != null) {
for (Integer subtaskId : epic.getSubtasks()) {
epicSubtasks.add(subtasks.get(subtaskId));
}
return epicSubtasks;
return epic.getSubtasks().stream().map(subtasks::get).collect(Collectors.toCollection(ArrayList::new));
} else {
System.out.println("Эпик не найден!");
return null;
Expand All @@ -74,14 +74,18 @@ public List<Task> getHistory() {

@Override
public void addTask(Task task) {
if (task.getId() == 0) {
if (isIntersectionTaskTime(task)) {
System.out.println("Задача пересекается по времени с другими");
} else if (task.getId() == 0) {
do {
taskId++;
task.setId(taskId);
} while (checkContainsAllTasks(task));
tasks.put(taskId, task);
prioritizedTasks.add(task);
} else if (!checkContainsAllTasks(task)) {
tasks.put(task.getId(), task);
prioritizedTasks.add(task);
} else {
System.out.println("Данные с таким id существуют в списке");
}
Expand All @@ -90,19 +94,25 @@ public void addTask(Task task) {
@Override
public void addSubtask(Subtask subtask) {
Epic epic = epics.get(subtask.getEpicId());
if (epic != null) {
if (isIntersectionTaskTime(subtask)) {
System.out.println("Подзадача пересекается по времени с другими");
} else if (epic != null) {
if (subtask.getId() == 0) {
do {
taskId++;
subtask.setId(taskId);
} while (checkContainsAllTasks(subtask));
subtasks.put(taskId, subtask);
prioritizedTasks.add(subtask);
epic.addSubtask(subtask);
updateEpicStatus(subtask.getEpicId());
updateEpicTimeInfo(subtask.getEpicId());
} else if (!checkContainsAllTasks(subtask)) {
subtasks.put(subtask.getId(), subtask);
prioritizedTasks.add(subtask);
epic.addSubtask(subtask);
updateEpicStatus(subtask.getEpicId());
updateEpicTimeInfo(subtask.getEpicId());
} else {
System.out.println("Данные с таким id существуют в списке");
}
Expand All @@ -113,7 +123,9 @@ public void addSubtask(Subtask subtask) {

@Override
public void addEpic(Epic epic) {
if (epic.getId() == 0) {
if (isIntersectionTaskTime(epic)) {
System.out.println("Эпик пересекается по времени с другими");
} else if (epic.getId() == 0) {
do {
taskId++;
epic.setId(taskId);
Expand All @@ -129,6 +141,7 @@ public void addEpic(Epic epic) {

@Override
public void deleteTask(int id) {
prioritizedTasks.remove(tasks.get(id));
tasks.remove(id);
historyManager.remove(id);
}
Expand All @@ -140,7 +153,9 @@ public void deleteSubtask(int id) {
Epic epic = epics.get(subtask.getEpicId());
epic.removeSubtask(id);
updateEpicStatus(subtask.getEpicId());
updateEpicTimeInfo(subtask.getEpicId());
}
prioritizedTasks.remove(subtask);
subtasks.remove(id);
historyManager.remove(id);
}
Expand All @@ -150,44 +165,40 @@ public void deleteEpic(int id) {
Epic epic = epics.remove(id);
historyManager.remove(id);
if (epic != null) {
for (Integer subtaskId : epic.getSubtasks()) {
epic.getSubtasks().forEach(subtaskId -> {
prioritizedTasks.remove(subtasks.get(subtaskId));
subtasks.remove(subtaskId);
historyManager.remove(subtaskId);
}
});
}


}

@Override
public void clearTasks() {
for (Integer taskId : tasks.keySet()) {
historyManager.remove(taskId);
}
tasks.values().forEach(prioritizedTasks::remove);
tasks.keySet().forEach(historyManager::remove);
tasks.clear();
}

@Override
public void clearSubtasks() {
for (Epic epic : epics.values()) {
epics.values().forEach(epic -> {
epic.clearSubtaskList();
epic.setStatus(StatusTask.NEW);
}
for (Integer subtaskId : subtasks.keySet()) {
historyManager.remove(subtaskId);
}
});
subtasks.values().forEach(prioritizedTasks::remove);
subtasks.keySet().forEach(historyManager::remove);
subtasks.clear();
}

@Override
public void clearEpics() {
for (Epic epic : epics.values()) {
epics.values().forEach(epic -> {
historyManager.remove(epic.getId());
for (Integer subtaskId : epic.getSubtasks()) {
historyManager.remove(subtaskId);
}
}
epic.getSubtasks().forEach(historyManager::remove);
});
epics.clear();
subtasks.values().forEach(prioritizedTasks::remove);
subtasks.clear();
}

Expand All @@ -198,7 +209,8 @@ public void updateTask(Task task) {
System.out.println("Не существует такой задачи");
return;
}

prioritizedTasks.remove(tasks.get(id));
prioritizedTasks.add(task);
tasks.put(id, task);
}

Expand All @@ -209,9 +221,11 @@ public void updateSubtask(Subtask subtask) {
System.out.println("Не существует такой подзадачи!");
return;
}

prioritizedTasks.remove(subtasks.get(id));
prioritizedTasks.add(subtask);
subtasks.put(id, subtask);
updateEpicStatus(subtask.getEpicId());
updateEpicTimeInfo(subtask.getEpicId());

}

Expand All @@ -228,6 +242,12 @@ public void updateEpic(Epic epic) {
epics.put(id, epic);
}

@Override
public TreeSet<Task> getPrioritizedTasks() {
return prioritizedTasks.stream().filter(task -> Objects.nonNull(task.getStartTime()))
.collect(Collectors.toCollection(() -> new TreeSet<>(comparator)));
}

private <T extends Task> boolean checkContainsAllTasks(T task) {
if (task == null) {
return false;
Expand Down Expand Up @@ -256,4 +276,30 @@ private void updateEpicStatus(int epicId) {

}

private void updateEpicTimeInfo(int epicId) {
Epic epic = epics.get(epicId);
LocalDateTime epicStartTime = epic.getSubtasks().stream().map(subtaskId -> subtasks.get(subtaskId)
.getStartTime()).filter(Objects::nonNull).min(Comparator.naturalOrder()).orElse(null);
LocalDateTime epicEndTime = epic.getSubtasks().stream().map(subtaskId -> subtasks.get(subtaskId)
.getEndTime()).filter(Objects::nonNull).max(Comparator.naturalOrder()).orElse(null);
Duration epicDuration = epic.getSubtasks().stream().map(subtaskId -> subtasks.get(subtaskId).getDuration())
.filter(Objects::nonNull).reduce(Duration.ZERO, Duration::plus);
epic.setStartTime(epicStartTime);
epic.setEndTime(epicEndTime);
epic.setDuration(epicDuration);
}

private boolean isIntersectionTaskTime(Task task) {
if (!Objects.nonNull(task.getStartTime()) && !Objects.nonNull(task.getEndTime())) {
return false;
} else {
List<Task> intersectionsTasks = getPrioritizedTasks().stream().filter(prioritezedTask ->
Objects.nonNull(prioritezedTask.getEndTime()))
.filter(prioritizedTask -> (prioritizedTask.getStartTime().isBefore(task.getStartTime())
&& prioritizedTask.getEndTime().isAfter(task.getStartTime())) ||
(prioritizedTask.getStartTime().equals(task.getStartTime()) && prioritizedTask.getEndTime().equals(task.getEndTime()))).toList();
return !intersectionsTasks.isEmpty();
}
}

}
3 changes: 3 additions & 0 deletions src/managers/TaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

public interface TaskManager {
ArrayList<Task> getTasks();
Expand All @@ -22,6 +23,8 @@ public interface TaskManager {

List<Task> getHistory();

TreeSet<Task> getPrioritizedTasks();

void addTask(Task task);

void addSubtask(Subtask subtask);
Expand Down
33 changes: 31 additions & 2 deletions src/tasks/Epic.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import statuses.StatusTask;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;

public class Epic extends Task {
Expand All @@ -13,6 +15,21 @@ public Epic(String name, String description, StatusTask status, int id) {
this.subtasks = new ArrayList<>();
}

public Epic(String name, String description, StatusTask status, int id, Duration duration, LocalDateTime startTime) {
super(name, description, status, id, duration, startTime);
this.subtasks = new ArrayList<>();
}

public Epic(String name, String description, StatusTask status, int id, Duration duration) {
super(name, description, status, id, duration);
this.subtasks = new ArrayList<>();
}

public Epic(String name, String description, StatusTask status, int id, LocalDateTime startTime) {
super(name, description, status, id, startTime);
this.subtasks = new ArrayList<>();
}

public Epic(String name, String description, int id) {
super(name, description, id);
this.subtasks = new ArrayList<>();
Expand Down Expand Up @@ -50,12 +67,24 @@ public void setSubtasks(ArrayList<Integer> subtasks) {

public static Epic fromString(String value) {
String[] taskInfo = value.split(",");
return new Epic(taskInfo[2], taskInfo[4], StatusTask.valueOf(taskInfo[3]), Integer.parseInt(taskInfo[0]));
if (taskInfo[6].equals("null") && taskInfo[7].equals("null")) {
return new Epic(taskInfo[2], taskInfo[4], StatusTask.valueOf(taskInfo[3]), Integer.parseInt(taskInfo[0]));
} else if (taskInfo[6].equals("null")) {
return new Epic(taskInfo[2], taskInfo[4], StatusTask.valueOf(taskInfo[3]), Integer.parseInt(taskInfo[0]),
LocalDateTime.parse(taskInfo[7]));
} else if (taskInfo[7].equals("null")) {
return new Epic(taskInfo[2], taskInfo[4], StatusTask.valueOf(taskInfo[3]), Integer.parseInt(taskInfo[0]),
Duration.parse(taskInfo[6]));
} else {
return new Epic(taskInfo[2], taskInfo[4], StatusTask.valueOf(taskInfo[3]), Integer.parseInt(taskInfo[0]),
Duration.parse(taskInfo[6]), LocalDateTime.parse(taskInfo[7]));
}
}

@Override
public String toString() {
return String.format("%d,%s,%s,%s,%s,", id, type, name, status, description);
return String.format("%d,%s,%s,%s,%s,,%s,%s,%s", id, type, name, status, description, duration, startTime,
endTime);
}

private boolean checkNotContainsSubtask(Subtask subtask) {
Expand Down
Loading