diff --git a/src/ru/gb/family_tree/Main.java b/src/ru/gb/family_tree/Main.java new file mode 100644 index 0000000..71b4d45 --- /dev/null +++ b/src/ru/gb/family_tree/Main.java @@ -0,0 +1,76 @@ +/** + * Реализовать, с учетом ооп подхода, приложение. + * Для проведения исследований с генеалогическим древом. + * Идея: описать некоторое количество компонент, например: + * модель человека и дерева + * Под “проведением исследования” можно понимать например получение всех детей выбранного человека. + * Более детальное описание проекта и как его реализовать обсуждали в конце семинара + * Сделать PR к проекту: https://github.com/Liberate520/homeWork + * В качестве ответа указать ссылку на PR + * Ссылка на то как сделать пулреквест смотри в материалах к уроку + * Если PR все таки не дается, то можно и ссылкой на гит репозиторий + * Дополнить проект методами записи в файл и чтения из файла. + * Для этого создать отдельный класс и реализовать в нем нужные методы. + * Для данного класса сделайте интерфейс, который и используйте в своей программе. + * Пример работы с интерфейсом Serialazable можно найти в материалах к уроку. + * Изменить древо, сделать класс параметизированным, + * чтобы условно дерево можно было использовать не только + * для людей, но и сделать родословную для собак (класс собак + * создавать не надо или создать, но за пределами пакета проекта). + * Продумать (только подумать, но можно и попробовать реализовать) + * класс общения с пользователем, набор команд, для операций над деревом + */ + +package ru.gb.family_tree; + +import ru.gb.family_tree.model.family_tree.FamilyTree; +import ru.gb.family_tree.model.human.Gender; +import ru.gb.family_tree.model.human.Human; +import ru.gb.family_tree.model.writer.FileHandler; + +import java.time.LocalDate; + +public class Main { + final static String filePath = "src/ru/gb/family_tree/writer/tree.txt"; + public static void main(String[] args) { + +// FamilyTree tree = load(); + FamilyTree tree = testTree(); + save(tree); + + System.out.println(tree); + } + + private static FamilyTree load() { + FileHandler fileHandler = new FileHandler(); + fileHandler.setPath(filePath); + return (FamilyTree) fileHandler.read(); + } + + public static void save(FamilyTree familyTree) { + FileHandler fileHandler = new FileHandler(); + fileHandler.setPath(filePath); + fileHandler.save(familyTree); + } + + private static FamilyTree testTree() { + FamilyTree tree = new FamilyTree(); + + Human sveta = new Human("Светлана", Gender.Female, LocalDate.of(1956, 2, 12), LocalDate.of(2023, 1, 14)); + Human vova1 = new Human("Владимир", Gender.Male, LocalDate.of(1954, 10, 23)); + + tree.add(sveta); + tree.add(vova1); +// tree.setWeddings(sveta, vova1); + + Human stepan = new Human("Степан", Gender.Male, LocalDate.of(1991, 12, 1), vova1, sveta); + Human polina = new Human("Полина", Gender.Female, LocalDate.of(1983, 9, 28), vova1, sveta); + Human vova2 = new Human("Владимир", Gender.Male, LocalDate.of(1996, 3, 1), vova1, sveta); + + tree.add(stepan); + tree.add(polina); + tree.add(vova2); + + return tree; + } +} diff --git a/src/ru/gb/family_tree/model/family_tree/FamilyTree.java b/src/ru/gb/family_tree/model/family_tree/FamilyTree.java new file mode 100644 index 0000000..aebd200 --- /dev/null +++ b/src/ru/gb/family_tree/model/family_tree/FamilyTree.java @@ -0,0 +1,162 @@ +package ru.gb.family_tree.model.family_tree; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class FamilyTree> implements Serializable, Iterable { + private long humansId; + private List humanList; + + public FamilyTree() { + this(new ArrayList<>()); + } + + public FamilyTree(List humanList) { + this.humanList = humanList; + } + + public boolean add(E human) { + if (human == null) { + return false; + } + if (!humanList.contains(human)) { + humanList.add(human); + human.setId(humansId++); + + addToParents(human); + addChildren(human); + + return true; + } + return false; + } + + private void addToParents(E human) { + for (E parent : human.getParents()) { + parent.addChild(human); + } + } + + private void addChildren(E human) { + for (E child : human.getChildren()) { + child.addParent(human); + } + } + + public List getSiblings(int id) { + E human = getById(id); + if (human == null) { + return null; + } + List res = new ArrayList<>(); + for (E parent : human.getParents()) { + for (E child : parent.getChildren()) { + if (!child.equals(human)) { + res.add(child); + } + } + } + return res; + } + + public List getByName(String name) { + List res = new ArrayList<>(); + for (E human : humanList) { + if (human.getName().equals(name)) { + res.add(human); + } + } + return res; + } + + public boolean setWeddings(long humansId1, long humansId2) { + if (checkId(humansId1) && checkId(humansId2)) { + E human1 = getById(humansId1); + E human2 = getById(humansId2); + return setWeddings(human1, human2); + } + return false; + } + + public boolean setWeddings(E human1, E human2) { + if (human1.getSpouse() == null && human2.getSpouse() == null) { + human1.getSpouse(human2); + human2.getSpouse(human1); + return true; + } else { + return false; + } + } + + public boolean setDivorce(long humansId1, long humansId2) { + if (checkId(humansId1) && checkId(humansId2)) { + E human1 = getById(humansId1); + E human2 = getById(humansId2); + return setDivorce(human1, human2); + } + return false; + } + + public boolean setDivorce(E human1, E human2) { + if (human1.getSpouse() != null && human2.getSpouse() != null) { + human1.getSpouse(null); + human2.getSpouse(null); + return true; + } else { + return false; + } + } + + public boolean remove(long humansId) { + if (checkId(humansId)) { + E human = getById(humansId); + return humanList.remove(human); + } + return false; + } + + public boolean checkId(long id) { + return id < humansId && id >= 0; + } + + public E getById(long id) { + for (E human : humanList) { + if (human.getId() == id) { + return human; + } + } + return null; + } + + @Override + public String toString() { + return getInfo(); + } + + public String getInfo() { + StringBuilder sb = new StringBuilder(); + sb.append("В дереве "); + sb.append(humanList.size()); + sb.append(" объектов: \n"); + for (E human : humanList) { + sb.append(human); + sb.append("\n"); + } + return sb.toString(); + } + + @Override + public Iterator iterator() { + return new FamilyTreeIterator(humanList); + } + + public void sortByName() { + humanList.sort(new FamilyTreeComparatorByName()); + } + + public void sortByBirthDate() { + humanList.sort(new FamilyTreeComparatorByBirthDate()); + } +} diff --git a/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByBirthDate.java b/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByBirthDate.java new file mode 100644 index 0000000..4e4b3da --- /dev/null +++ b/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByBirthDate.java @@ -0,0 +1,10 @@ +package ru.gb.family_tree.model.family_tree; + +import java.util.Comparator; + +public class FamilyTreeComparatorByBirthDate> implements Comparator { + @Override + public int compare(T o1, T o2) { + return o1.getBirthDate().compareTo(o2.getBirthDate()); + } +} diff --git a/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByName.java b/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByName.java new file mode 100644 index 0000000..3ce8559 --- /dev/null +++ b/src/ru/gb/family_tree/model/family_tree/FamilyTreeComparatorByName.java @@ -0,0 +1,10 @@ +package ru.gb.family_tree.model.family_tree; + +import java.util.Comparator; + +public class FamilyTreeComparatorByName> implements Comparator { + @Override + public int compare(T o1, T o2) { + return o1.getName().compareTo(o2.getName()); + } +} diff --git a/src/ru/gb/family_tree/model/family_tree/FamilyTreeIterator.java b/src/ru/gb/family_tree/model/family_tree/FamilyTreeIterator.java new file mode 100644 index 0000000..6164686 --- /dev/null +++ b/src/ru/gb/family_tree/model/family_tree/FamilyTreeIterator.java @@ -0,0 +1,24 @@ +package ru.gb.family_tree.model.family_tree; + +import java.util.Iterator; +import java.util.List; + +public class FamilyTreeIterator> implements Iterator { + private List list; + private int index; + + public FamilyTreeIterator(List list) { + this.list = list; + index = 0; + } + + @Override + public boolean hasNext() { + return index < list.size(); + } + + @Override + public T next() { + return list.get(index++); + } +} diff --git a/src/ru/gb/family_tree/model/family_tree/TreeNode.java b/src/ru/gb/family_tree/model/family_tree/TreeNode.java new file mode 100644 index 0000000..4498f9b --- /dev/null +++ b/src/ru/gb/family_tree/model/family_tree/TreeNode.java @@ -0,0 +1,21 @@ +package ru.gb.family_tree.model.family_tree; + +import java.io.Serializable; +import java.time.LocalDate; +import java.util.List; + +public interface TreeNode extends Serializable { + void setId(long id); + long getId(); + T getFather(); + T getMother(); + boolean addChild(T human); + boolean addParent(T human); + String getName(); + LocalDate getDeathDate(); + LocalDate getBirthDate(); + List getParents(); + List getChildren(); + T getSpouse(); + void setSpouse(); +} diff --git a/src/ru/gb/family_tree/model/human/Gender.java b/src/ru/gb/family_tree/model/human/Gender.java new file mode 100644 index 0000000..e278515 --- /dev/null +++ b/src/ru/gb/family_tree/model/human/Gender.java @@ -0,0 +1,5 @@ +package ru.gb.family_tree.model.human; + +public enum Gender { + Male, Female +} diff --git a/src/ru/gb/family_tree/model/human/Human.java b/src/ru/gb/family_tree/model/human/Human.java new file mode 100644 index 0000000..19ba764 --- /dev/null +++ b/src/ru/gb/family_tree/model/human/Human.java @@ -0,0 +1,230 @@ +package ru.gb.family_tree.model.human; + +import ru.gb.family_tree.model.family_tree.TreeNode; + +import java.time.LocalDate; +import java.time.Period; +import java.util.ArrayList; +import java.util.List; + +public abstract class Human implements TreeNode { + private long id; + private String name; + private Gender gender; + private LocalDate birthDate; + private LocalDate deathDate; + private Human mother; + private Human father; + private List children; + private Human spouse; + + public Human(String name, Gender gender, LocalDate birthDate, LocalDate deathDate, Human father, Human mother) { + id = -1; + this.name = name; + this.gender = gender; + this.birthDate = birthDate; + this.deathDate = deathDate; + this.father = father; + this.mother = mother; + children = new ArrayList<>(); + } + + public Human(String name, Gender gender, LocalDate birthDate) { + this(name, gender, birthDate, null, null, null); + } + + public Human(String name, Gender gender, LocalDate birthDate, LocalDate deathDate) { + this(name, gender, birthDate, deathDate, null, null); + } + + public Human(String name, Gender gender, LocalDate birthDate, + Human father, Human mother) { + this(name, gender, birthDate, null, father, mother); + } + + public boolean addChild(Human child) { + if (!children.contains(child)) { + children.add(child); + return true; + } + return false; + } + + public boolean addParent(Human parent) { + if (parent.getGender().equals(Gender.Male)) { + setFather(parent); + } else if (parent.getGender().equals(Gender.Female)) { + setMother(parent); + } + return true; + } + + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } + + public LocalDate getDeathDate() { + return deathDate; + } + + public void setDeathDate(LocalDate deathDate) { + this.deathDate = deathDate; + } + + public Human getMother() { + return mother; + } + + public void setMother(Human mother) { + this.mother = mother; + } + + public Human getFather() { + return father; + } + + public void setFather(Human father) { + this.father = father; + } + + public Human getSpouse() { + return spouse; + } + + public void setSpouse(Human spouse) { this.spouse = spouse; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public List getParents() { + List list = new ArrayList<>(2); + if (father != null) { + list.add(father); + } + if (mother != null) { + list.add(mother); + } + return list; + } + + public int getAge() { + if (deathDate == null) { + return getPeriod(birthDate, LocalDate.now()); + } else { + return getPeriod(birthDate, deathDate); + } + } + + private int getPeriod(LocalDate birthDate, LocalDate deathDate) { + Period diff = Period.between(birthDate, deathDate); + return diff.getYears(); + } + + @Override + public String toString() { + return getInfo(); + } + + public String getInfo() { + StringBuilder sb = new StringBuilder(); + sb.append("имя: "); + sb.append(name); + sb.append(", пол: "); + sb.append(getGender()); + sb.append(", возраст: "); + sb.append(getAge()); + sb.append(", "); + sb.append(getMotherInfo()); + sb.append(", "); + sb.append(getFatherInfo()); + sb.append(", "); + sb.append(getChildrenInfo()); + return sb.toString(); + } + + public String getMotherInfo() { + String res = "мать: "; + Human mother = getMother(); + if (mother != null) { + res += mother.getName(); + } else { + res += "нет информации"; + } + return res; + } + + + public String getFatherInfo() { + String res = "отец: "; + Human father = getFather(); + if (father != null) { + res += father.getName(); + } else { + res += "нет информации"; + } + return res; + } + + + public String getChildrenInfo() { + StringBuilder res = new StringBuilder(); + res.append("дети: "); + if (children.size() != 0) { + res.append(children.get(0).getName()); + for (int i = 1; i < children.size(); i++) { + res.append(", "); + res.append(children.get(1).getName()); + } + } else { + res.append("отсутствуют"); + } + return res.toString(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Human)) { + return false; + } + Human human = (Human) obj; + return human.getId() == getId(); + } +} diff --git a/src/ru/gb/family_tree/model/writer/FileHandler.java b/src/ru/gb/family_tree/model/writer/FileHandler.java new file mode 100644 index 0000000..fc44ae7 --- /dev/null +++ b/src/ru/gb/family_tree/model/writer/FileHandler.java @@ -0,0 +1,34 @@ +package ru.gb.family_tree.model.writer; + +import java.io.*; + +public class FileHandler implements Writer { + private String filePath; + + @Override + public boolean save(Serializable serializable) { + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath))) { + objectOutputStream.writeObject(serializable); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + @Override + public Object read() { + try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath))) { + ; + return objectInputStream.readObject(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + @Override + public void setPath(String filePath) { + this.filePath = filePath; + } +} diff --git a/src/ru/gb/family_tree/model/writer/Writer.java b/src/ru/gb/family_tree/model/writer/Writer.java new file mode 100644 index 0000000..2881651 --- /dev/null +++ b/src/ru/gb/family_tree/model/writer/Writer.java @@ -0,0 +1,9 @@ +package ru.gb.family_tree.model.writer; + +import java.io.Serializable; + +public interface Writer { + boolean save(Serializable serializable); + Object read(); + void setPath(String filePath); +}