2011-01-06 4 views
1

J'essaie de calcler la meilleure façon de supprimer un noeud dans un arbre généalogique. D'abord, une petite description de la façon dont l'application fonctionne.Suppression d'un noeud dans un arbre généalogique

Mon application fait l'hypothèse suivante:

Tout noeud ne peut avoir qu'un seul partenaire. Cela signifie que si un enfant a un seul noeud, il sera aussi l'enfant des nœuds partenaires. Par conséquent, les relations par étapes, les divorces, etc. ne sont pas compensés. Un nœud a toujours deux parents - Une mère et un père ne peuvent pas être ajoutés séparément. Si l'utilisateur ne connaît pas les détails, les attributs de noeud sont définis sur une valeur par défaut.

Aussi n'importe quel noeud peut ajouter des parents, des frères et sœurs, des enfants à lui-même. Par conséquent, les relations juridiques peuvent être ajoutées.

EDIT: Après avoir étudié la réponse d'Andreas, j'ai réalisé que mon code pourrait avoir besoin d'être retravaillé. J'essaie d'ajouter ma source mais ça dépasse la limite des caractères ... Des conseils?

Voici la FamilyTree Classe:

package familytree; 

import java.io.PrintStream; 
public class FamilyTree { 
    private static final int DISPLAY_FAMILY_MEMBERS = 1; 
    private static final int ADD_FAMILY_MEMBER = 2; 
    private static final int REMOVE_FAMILY_MEMBER = 3; 
    private static final int EDIT_FAMILY_MEMBER = 4; 
    private static final int SAVE_FAMILY_TREE = 5; 
    private static final int LOAD_FAMILY_TREE = 6; 
    private static final int DISPLAY_ANCESTORS = 7; 
    private static final int DISPLAY_DESCENDANTS = 8; 
    private static final int QUIT = 9; 
    private Input in; 
    private Family family; 
    private PrintStream out; 

    public FamilyTree(Input in, PrintStream out) { 
     this.in = in; 
     this.out = out; 
     family = new Family(); 
    } 

    public void start() { 
     out.println("\nWelcome to the Family Tree Builder"); 
     initialise(); 
     while (true) { 
      displayFamilyTreeMenu(); 
      int command = getCommand(); 
      if (quit(command)) { 
       break; 
      } 
      executeOption(command); 
     } 
    } 

    private int getCommand() { 
     return getInteger("\nEnter command: "); 
    } 

    private int getInteger(String message) { 
     while (true) { 
      out.print(message); 
      if (in.hasNextInt()) { 
       int n = in.nextInt(); 
       in.nextLine(); 
       return n; 
      } else { 
       in.nextLine(); 
       out.println("Your input was not understood. Please try again."); 
      } 
     } 
    } 

    //good 
    private void displayFamilyTreeMenu() { 
     out.println("\nFamily Tree Menu"); 
     out.println(DISPLAY_FAMILY_MEMBERS + ". Display Family Members"); 
     out.println(ADD_FAMILY_MEMBER + ". Add Family Member"); 
     out.println(REMOVE_FAMILY_MEMBER + ". Remove Family Member"); 
     out.println(EDIT_FAMILY_MEMBER + ". Edit Family Member"); 
     out.println(SAVE_FAMILY_TREE + ". Save Family Tree"); 
     out.println(LOAD_FAMILY_TREE + ". Load Family Tree"); 
     out.println(DISPLAY_ANCESTORS + ". Display Ancestors"); 
     out.println(DISPLAY_DESCENDANTS + ". Display Descendants"); 
     out.println(QUIT + ". Quit"); 
    } 

    //good 
    private boolean quit(int opt) { 
     return (opt == QUIT) ? true : false; 
    } 

    //good 
    private void executeOption(int choice) { 
     switch (choice) { 
      case DISPLAY_FAMILY_MEMBERS: 
       displayFamilyMembers(); 
       break; 
      case ADD_FAMILY_MEMBER: 
       addFamilyMember(); 
       break; 
      case REMOVE_FAMILY_MEMBER: 
       removeMember(); 
       break; 
      case EDIT_FAMILY_MEMBER: 
       editMember(); 
       break; 
      case SAVE_FAMILY_TREE: 
       saveFamilyTree(); 
       break; 
      case LOAD_FAMILY_TREE: 
       loadFamilyTree(); 
       break; 
      case DISPLAY_ANCESTORS: 
       displayAncestors(); 
       break; 
      case DISPLAY_DESCENDANTS: 
       displayDescendants(); 
       break; 
      default: 
       out.println("Not a valid option! Try again."); 
       break; 
     } 
    } 

    private void removeMember() { 
     displayFamilyMembers(); 
     int choice = selectMember(); 
     if (choice >= 0) { 
      FamilyMember f = family.getFamilyMember(choice); 
      if (f.getIndex() == 0) { 
       out.println("Cannot delete yourself!"); 
       return; 
      } 

      deleteMember(f); 
     } 
    } 

    private void deleteMember(FamilyMember f) { 
     //remove from tree 
     family.removeMember(f); 

     //remove all links to this person 
     if (f.hasParents()) { 
      f.getMother().removeChild(f); 
      f.getFather().removeChild(f); 
     } 
     if(f.getPartner()!=null){ 
      f.getPartner().setPartner(null); 
      f.setPartner(null); 
     } 

     if (f.hasChildren()) { 
      for (FamilyMember member : f.getChildren()) { 
       if (f == member.getMother()) { 
        member.setMother(null); 
       } 
       if (f == member.getFather()) { 
        member.setFather(null); 
       } 
       if (f == member.getPartner()) { 
        member.setPartner(null); 
       } 
      } 
     } 
    } 

    private void saveFamilyTree() { 
     out.print("Enter file name: "); 
     String fileName = in.nextLine(); 
     FileOutput output = new FileOutput(fileName); 
     family.save(output); 
     output.close(); 
     saveRelationships(); 
    } 

    private void saveRelationships() { 
     FileOutput output = new FileOutput("Relationships.txt"); 
     family.saveRelationships(output); 
     output.close(); 
    } 

    private void loadFamilyTree() { 
     out.print("Enter file name: "); 
     String fileName = in.nextLine(); 
     FileInput input = new FileInput(fileName); 
     family.load(input); 
     input.close(); 
     loadRelationships(); 
    } 

    private void loadRelationships() { 
     FileInput input = new FileInput("Relationships.txt"); 
     family.loadRelationships(input); 
     input.close(); 
    } 

    //for selecting family member for editing adding nodes etc 
    private void displayFamilyMembers() { 
     out.println("\nDisplay Family Members"); 
     int count = 0; 
     for (FamilyMember member : family.getFamilyMembers()) { 
      out.println(); 
      if (count + 1 < 10) { 
       out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName()); 
       out.println(" " + member.getGender()); 
       out.println(" " + member.getDob()); 
       out.println(" Generation: " + (member.getGeneration() + 1)); 
      } else { 
       out.println((count + 1) + ". " + member.getFirstName() + " " + member.getLastName()); 
       out.println(" " + member.getGender()); 
       out.println(" " + member.getDob()); 
       out.println(" Generation: " + (member.getGeneration() + 1)); 
      } 
      count++; 
     } 
    } 

    private int selectRelative() { 
     out.println("\nSelect Relative"); 
     out.println("1. Add Parents"); 
     out.println("2. Add Child"); 
     out.println("3. Add Partner"); 
     out.println("4. Add Sibling"); 
     //out.print("\nEnter Choice: "); 
     //int choice = in.nextInt(); 
     int choice = getInteger("\nEnter Choice: "); 
     if (choice > 0 && choice < 5) { 
      return choice; 
     } 
     return (-1); 
    } 

    private void addFamilyMember() { 
     if (family.getFamilyMembers().isEmpty()) { 
      out.println("No Members To Add To"); 
      return; 
     } 
     int memberIndex = selectMember(); 
     if (memberIndex >= 0) { 
      FamilyMember member = family.getFamilyMember(memberIndex); 
      int relative = selectRelative(); 
      if (relative > 0) { 
       out.println("\nAdd Member"); 
       //if choice is valid 
       switch (relative) { 
        case 1: 
         //adding parents 
         FamilyMember mum, dad; 
         if (!member.hasParents()) { 
          out.println("Enter Mothers Details"); 
          mum = addMember(relative, "Female"); 
          out.println("\nEnter Fathers Details"); 
          dad = addMember(relative, "Male"); 
          member.linkParent(mum); 
          member.linkParent(dad); 
          mum.linkPartner(dad); 
          mum.setGeneration(member.getGeneration() - 1); 
          dad.setGeneration(member.getGeneration() - 1); 
          sortGenerations(); 
         } else { 
          out.println(member.getFirstName() + " " + member.getLastName() + " already has parents."); 
         } 
         break; 
        case 2: 
         //adding child 
         if (member.getPartner() == null) { 
          FamilyMember partner; 
          if (member.getGender().equals("Male")) { 
           out.println("Enter Mothers Details"); 
           partner = addMember(1, "Female"); 
          } else { 
           out.println("Enter Fathers Details"); 
           partner = addMember(1, "Male"); 
          } 
          //create partner 
          member.linkPartner(partner); 
          partner.setGeneration(member.getGeneration()); 
          out.println(); 
         } 
         out.println("Enter Childs Details"); 
         FamilyMember child = addMember(relative, ""); 
         child.linkParent(member); 
         child.linkParent(member.getPartner()); 
         child.setGeneration(member.getGeneration() + 1); 
         sortGenerations(); 
         break; 
        case 3: 
         //adding partner 
         if (member.getPartner() == null) { 
          out.println("Enter Partners Details"); 
          FamilyMember partner = addMember(relative, ""); 
          member.linkPartner(partner); 
          partner.setGeneration(member.getGeneration()); 
         } else { 
          out.println(member.getFirstName() + " " + member.getLastName() + " already has a partner."); 
         } 
         break; 
        case 4: 
         //adding sibling 
         if (member.getFather() == null) { 
          out.println("Enter Mothers Details"); 
          mum = addMember(1, "Female"); 
          out.println("\nEnter Fathers Details"); 
          dad = addMember(1, "Male"); 
          member.linkParent(mum); 
          member.linkParent(dad); 
          mum.linkPartner(dad); 
          mum.setGeneration(member.getGeneration() - 1); 
          dad.setGeneration(member.getGeneration() - 1); 
          sortGenerations(); 
          out.println("\nEnter Siblings Details"); 
         } else { 
          out.println("Enter Siblings Details"); 
         } 
         FamilyMember sibling = addMember(relative, ""); 

         //create mum and dad 
         mum = member.getMother(); 
         dad = member.getFather(); 
         sibling.linkParent(mum); 
         sibling.linkParent(dad); 
         sibling.setGeneration(member.getGeneration()); 
         break; 
       } 
      } else { 
       out.println("Invalid Option!"); 
      } 
     } else { 
      out.println("Invalid Option!"); 
     } 
    } 

    private int selectMember() { 
     displayFamilyMembers(); 
     //out.print("\nSelect Member: "); 
     //int choice = in.nextInt(); 
     int choice = getInteger("\nSelect Member: "); 
     if (choice > 0 && choice <= family.getFamilyMembers().size()) { 
      return (choice - 1); 
     } 
     return -1; 
    } 

    private void editMember() { 
     int choice = selectMember(); 
     if (choice >= 0) { 
      out.println("Select Detail To Edit: "); 
      out.println("1. Name"); 
      out.println("2. Gender"); 
      out.println("3. Date of Birth"); 
      //out.print("\nEnter Choice: "); 
      //int opt = in.nextInt(); 
      int opt = getInteger("\nEnter Choice: "); 
      if (opt > 0 && opt < 4) { 
       switch (opt) { 
        case 1: //name 
         out.print("Enter New First Name: "); 
         String fName = in.nextLine(); 
         out.print("Enter New Last Name: "); 
         String lName = in.nextLine(); 
         family.changeName(fName, lName, choice); 
         break; 
        case 2: //Gender 
         FamilyMember f = family.getFamilyMember(choice); 
         String gender = f.getGender(); 
         if (f.getChildren().isEmpty()) { 
          gender = selectGender(); 
          family.changeGender(gender, choice); 
         } else { 
          //swap genders 
          //swap mother father relationships for kids 
          swapGenders(f, choice); 
         } 
         break; 
        case 3: 
         String dob = enterDateOfBirth(); 
         family.changeDOB(dob, choice); 
       } 
      } else { 
       out.println("Invalid Choice!"); 
      } 
     } 

    } 

    private FamilyMember addMember(int option, String gender) { 
     out.print("Enter First Name: "); 
     String fName = formatString(in.nextLine().trim()); 
     out.print("Enter Last Name: "); 
     String lName = formatString(in.nextLine().trim()); 
     //String gender; 
     if (option != 1) { //if not adding parents 
      gender = selectGender(); 
     } 
     String dob = enterDateOfBirth(); 
     FamilyMember f = family.getFamilyMember(family.addMember(fName, lName, gender, dob)); 
     f.setIndex(family.getFamilyMembers().size() - 1); 
     return (f); 
    } 

    private String selectGender() { 
     String gender = null; 
     out.println("Select Gender"); 
     out.println("1. Male"); 
     out.println("2. Female"); 
     //out.print("Enter Choice: "); 
     //int gOpt = in.nextInt(); 
     int gOpt = getInteger("Enter Choice: "); 
     if (gOpt == 1) { 
      gender = "Male"; 
     } else if (gOpt == 2) { 
      gender = "Female"; 
     } else { 
      out.println("Invalid Choice"); 
     } 
     return gender; 
    } 

    private void swapGenders(FamilyMember f, int choice) { 
     String gender; 
     out.println("\nNOTE: Editing A Parent Nodes Gender Will Swap Parents Genders\n" 
       + "And Swap Mother/Father Relationships For All Children."); 
     out.println("\nContinue:"); 
     out.println("1. Yes"); 
     out.println("2. No"); 
     //out.print("\nEnter Choice: "); 
     //int select = in.nextInt(); 
     int select = getInteger("\nEnter Choice: "); 
     if (select > 0 && select < 3) { 
      switch (select) { 
       case 1: 
        //swap relationships 
        gender = selectGender(); 
        //if selected gender is different 
        if (!gender.equals(f.getGender())) { 
         //swap 
         String g = f.getGender(); 
         family.changeGender(gender, choice); 
         family.changeGender(g, f.getPartner().getIndex()); 
         if (g.equals("Male")) { 
          for (FamilyMember m : f.getChildren()) { 
           m.setMother(f); 
           m.setFather(f.getPartner()); 
          } 
         } else { 
          for (FamilyMember m : f.getChildren()) { 
           m.setFather(f); 
           m.setMother(f.getPartner()); 
          } 
         } 
        } 
        break; 
       case 2: 
        break; 
      } 
     } else { 
      out.println("Invalid Choice"); 
     } 
    } 

    private String formatString(String s) { 
     String firstLetter = s.substring(0, 1); 
     String remainingLetters = s.substring(1, s.length()); 
     s = firstLetter.toUpperCase() + remainingLetters.toLowerCase(); 
     return s; 
    } 

    private String enterDateOfBirth() { 
     out.print("Enter Year Of Birth (0 - 2011): "); 
     String y = in.nextLine(); 

     out.print("Enter Month Of Birth (1-12): "); 
     String m = in.nextLine(); 
     if (m.trim().equals("")) { 
      m = "0"; 
     } 
     if (Integer.parseInt(m) < 10) { 
      m = "0" + m; 
     } 
     m += "-"; 

     out.print("Enter Date of Birth (1-31): "); 
     String d = in.nextLine(); 

     if (d.trim().equals("")) { 
      d = "0"; 
     } 
     if (Integer.parseInt(d) < 10) { 
      d = "0" + d; 
     } 
     d += "-"; 

     String dob = d + m + y; 
     while (!DateValidator.isValid(dob)) { 
      out.println("Invalid Date. Try Again:"); 
      dob = enterDateOfBirth(); 
     } 
     return (dob); 
    } 

    private void displayAncestors() { 
     out.print("\nDisplay Ancestors For Which Member: "); 
     int choice = selectMember(); 
     if (choice >= 0) { 
      FamilyMember node = family.getFamilyMember(choice); 
      FamilyMember ms = findRootNode(node, 0, 2, -1); 
      FamilyMember fs = findRootNode(node, 1, 2, -1); 
      out.println("\nPrint Ancestors"); 
      out.println("\nMothers Side"); 
      if(ms==null){ 
       out.println("Member has no mother"); 
      }else{ 
       printDescendants(ms, node, ms.getGeneration()); 
      } 
      out.println("\nFathers Side"); 
      if(fs==null){ 
       out.println("Member has no father"); 
      }else{ 
       printDescendants(fs, node, fs.getGeneration()); 
      } 
     } else { 
      out.println("Invalid Option!"); 
     } 
    } 

    private void displayDescendants() { 
     out.print("\nDisplay Descendants For Which Member: "); 
     int choice = selectMember(); 
     if (choice >= 0) { 
      FamilyMember node = family.getFamilyMember(choice); 
      out.println("\nPrint Descendants"); 
      printDescendants(node, null, 0); 
     } else { 
      out.println("Invalid Option!"); 
     } 
    } 

    private FamilyMember findRootNode(FamilyMember node, int parent, int numGenerations, int count) { 
     FamilyMember root; 
     count++; 
     if (count < numGenerations) { 
      if (parent == 0) { 
       if(node.hasMother()){ 
        node = node.getMother(); 
       }else{ 
        return node; 
       } 
      } else { 
       if(node.hasFather()){ 
        node = node.getFather(); 
       }else{ 
        return node; 
       } 
      } 
      root = findRootNode(node, 1, numGenerations, count); 
      return root; 
     } 

     return node; 
    } 

    private int findHighestLeafGeneration(FamilyMember node) { 
     int gen = node.getGeneration(); 
     for (int i = 0; i < node.getChildren().size(); i++) { 
      int highestChild = findHighestLeafGeneration(node.getChild(i)); 
      if (highestChild > gen) { 
       gen = highestChild; 
      } 
     } 
     return gen; 
    } 

    private void printDescendants(FamilyMember root, FamilyMember node, int gen) { 
     out.print((root.getGeneration() + 1) + " " + root.getFullName()); 
     out.print(" [" + root.getDob() + "] "); 
     if (root.getPartner() != null) { 
      out.print("+Partner: " + root.getPartner().getFullName() + " [" + root.getPartner().getDob() + "] "); 
     } 
     if (root == node) { 
      out.print("*"); 
     } 
     out.println(); 

     if (!root.getChildren().isEmpty() && root != node) { 
      for (int i = 0; i < root.getChildren().size(); i++) { 
       for (int j = 0; j < root.getChild(i).getGeneration() - gen; j++) { 
        out.print(" "); 
       } 
       printDescendants(root.getChild(i), node, gen); 
      } 
     } else { 
      return; 
     } 
    } 

    //retrieve highest generation 
    public int getRootGeneration() { 
     int min = family.getFamilyMember(0).getGeneration(); 
     for (int i = 0; i < family.getFamilyMembers().size(); i++) { 
      min = Math.min(min, family.getFamilyMember(i).getGeneration()); 
     } 
     return Math.abs(min); 
    } 

    public void sortGenerations() { 
     int amount = getRootGeneration(); 
     for (FamilyMember member : family.getFamilyMembers()) { 
      member.setGeneration(member.getGeneration() + amount); 
     } 
    } 

    //test method - temporary 
    private void initialise() { 
     family.addMember("Bart", "Simpson", "Male", "18-03-1985"); 
     family.getFamilyMember(0).setIndex(0); 
     family.addMember("Homer", "Simpson", "Male", "24-09-1957"); 
     family.getFamilyMember(1).setIndex(1); 
     family.addMember("Marge", "Simpson", "Female", "20-07-1960"); 
     family.getFamilyMember(2).setIndex(2); 
     family.addMember("Lisa", "Simpson", "Female", "28-01-1991"); 
     family.getFamilyMember(3).setIndex(3); 
     family.addMember("Abe", "Simpson", "Male", "10-03-1920"); 
     family.getFamilyMember(4).setIndex(4); 
     family.addMember("Mona", "Simpson", "Female", "18-09-1921"); 
     family.getFamilyMember(5).setIndex(5); 


     //set relationships 
     family.getFamilyMember(0).setMother(family.getFamilyMember(2)); 
     family.getFamilyMember(0).setFather(family.getFamilyMember(1)); 
     family.getFamilyMember(3).setMother(family.getFamilyMember(2)); 
     family.getFamilyMember(3).setFather(family.getFamilyMember(1)); 


     family.getFamilyMember(1).addChild(family.getFamilyMember(3)); 
     family.getFamilyMember(1).addChild(family.getFamilyMember(0)); 

     family.getFamilyMember(2).addChild(family.getFamilyMember(3)); 
     family.getFamilyMember(2).addChild(family.getFamilyMember(0)); 

     family.getFamilyMember(1).setPartner(family.getFamilyMember(2)); 
     family.getFamilyMember(2).setPartner(family.getFamilyMember(1)); 

     family.getFamilyMember(4).setPartner(family.getFamilyMember(5)); 
     family.getFamilyMember(5).setPartner(family.getFamilyMember(4)); 

     family.getFamilyMember(1).setMother(family.getFamilyMember(5)); 
     family.getFamilyMember(1).setFather(family.getFamilyMember(4)); 

     family.getFamilyMember(4).addChild(family.getFamilyMember(1)); 
     family.getFamilyMember(5).addChild(family.getFamilyMember(1)); 

     family.getFamilyMember(0).setGeneration(2); 
     family.getFamilyMember(1).setGeneration(1); 
     family.getFamilyMember(2).setGeneration(1); 
     family.getFamilyMember(3).setGeneration(2); 
     family.getFamilyMember(4).setGeneration(0); 
     family.getFamilyMember(5).setGeneration(0); 
    } 
} 
+8

Quel titre merveilleusement consonance sinistre ... – skaffman

+2

Vous avez besoin d'une balle d'argent pour cette ? –

+0

une balle d'argent serait idéal - si elle existe! – user559142

Répondre

3

Toutes les tâches exigent le même effort. Il sera toujours se présenter comme suit:

public void deleteFamilyMember(FamilyMember member) { 
    member.mother.children.remove(member); 
    member.father.children.remove(member); 
    member.partner.children.remove(member); 
    for (FamilyMember child:children) { 
    if (child.father == member) child.father = null; 
    if (child.mother == member) child.mother = null; 
    if (child.partner == member) child.partner = null; 
    } 
    // now all references to this member are eliminated, gc will do the rest. 
} 

Exemple:

Homer.mother = ?? 
Homer.father = ?? 
Homer.partner = Marge 
Homer.children = {Bart, Lisa, Maggie} 

Marge.mother = ?? 
Marge.father = ?? 
Marge.partner = Homer 
Marge.children = {Bart, Lisa, Maggie} 

Bart.mother = Marge 
Bart.father = Homer 
Bart.partner = null 
Bart.children = {} 

Lisa.mother = Marge 
Lisa.father = Homer 
Lisa.partner = null 
Lisa.children = {} 

Maggie.mother = Marge 
Maggie.father = Homer 
Maggie.partner = null 
Maggie.children = {} 

Pour supprimer Bart de l'arbre familiar, nous devrait ensemble attribuer à null et la mère de Bart et son père besoin à retirer Bart de la liste des enfants de Homer et Marge.

Pour supprimer Marge, nous devons mettre son partenaire partenaire null (Homer.partner) et visitez tous les enfants pour effacer leur attribut mother (qui est cette child.mother partie du code ci-dessus)

+0

Merci pour la réponse - quelle est la signification de member.partner.children.remove (member); – user559142

+0

@ user559142 - assez évident: une mère ** a-un ** enfant et ce garçon ou fille ** a-a ** mère. Nous devrions supprimer une référence à la mère de * l'enfant * et devons retirer cet enfant de la liste des enfants de sa mère et de son père (et de son partenaire). –

+0

Ok, je comprends ce que vous dites et je suis d'accord. Mais que se passe-t-il si Bart a un partenaire. Le partenaire de Barts a ajouté sa mère, papa etc. L'utilisateur supprime alors Bart. Il s'ensuit que je devrais alors supprimer le partenaire de Barts et ses parents, tous les enfants que Bart pourrait avoir car le lien entre les familles n'est plus là. C'est mon problème. – user559142

1

Je modélise les choses différemment et faire le travail dans la classe FamilyMember.Voici un exemple d'implémentation:

public class FamilyMember{ 

    public enum Gender{ 
     MALE, FEMALE 
    } 

    private final Set<FamilyMember> exPartners = 
     new LinkedHashSet<FamilyMember>(); 

    public Set<FamilyMember> getExPartners(){ 
     return new LinkedHashSet<FamilyMember>(exPartners); 
    } 

    public FamilyMember getFather(){ 
     return father; 
    } 

    public FamilyMember getMother(){ 
     return mother; 
    } 

    public Set<FamilyMember> getSiblings(){ 
     final Set<FamilyMember> set = 
      father == null && mother == null ? Collections 
       .<FamilyMember> emptySet() : new HashSet<FamilyMember>(); 
     if(father != null){ 
      set.addAll(father.children); 
     } 
     if(mother != null){ 
      set.addAll(mother.children); 
     } 
     set.remove(this); 
     return set; 
    } 

    public String getName(){ 
     return name; 
    } 

    private final Gender gender; 
    private FamilyMember partner; 
    private final FamilyMember father; 
    private final FamilyMember mother; 
    private final Set<FamilyMember> children = 
     new LinkedHashSet<FamilyMember>(); 
    private final String name; 

    public FamilyMember haveChild(final String name, final Gender gender){ 
     if(partner == null){ 
      throw new IllegalStateException("Partner needed"); 
     } 
     final FamilyMember father = gender == Gender.MALE ? this : partner; 
     final FamilyMember mother = father == this ? partner : this; 
     return new FamilyMember(father, mother, name, gender); 
    } 

    public Set<FamilyMember> getChildren(){ 
     return new LinkedHashSet<FamilyMember>(children); 
    } 

    @Override 
    public String toString(){ 

     return "[" + name + ", " + gender + "]"; 
    } 

    public FamilyMember(final String name, final Gender gender){ 
     this(null, null, name, gender); 
    } 

    public FamilyMember(final FamilyMember father, 
     final FamilyMember mother, 
     final String name, 
     final Gender gender){ 
     if(name == null){ 
      throw new IllegalArgumentException("A kid needs a name!"); 
     } 
     if(gender == null){ 
      throw new IllegalArgumentException("Which is it going to be?"); 
     } 
     this.father = father; 
     this.name = name; 
     this.gender = gender; 
     if(father != null){ 
      father.children.add(this); 
     } 
     this.mother = mother; 
     if(mother != null){ 
      mother.children.add(this); 
     } 
    } 

    public FamilyMember hookUpWith(final FamilyMember partner){ 
     if(partner.gender == gender){ 
      throw new IllegalArgumentException(
       "Sorry, same-sex-marriage would make things too complicated"); 
     } 
     this.partner = partner; 
     partner.partner = this; 
     return this; 
    } 

    public FamilyMember splitUp(){ 
     if(partner == null){ 
      throw new IllegalArgumentException("Hey, I don't have a partner"); 
     } else{ 
      partner.partner = null; 
      exPartners.add(partner); 
      partner.exPartners.add(this); 
      partner = null; 
     } 
     return this; 
    } 

    public FamilyMember getPartner(){ 
     return partner; 
    } 

} 

Et voici le code beaucoup plus expressif que vous pouvez écrire de cette façon:

FamilyMember marge = new FamilyMember("Marge", Gender.FEMALE); 
FamilyMember homer = new FamilyMember("Homer", Gender.MALE); 
homer.hookUpWith(marge); 
FamilyMember bart = homer.haveChild("Bart", Gender.MALE); 
FamilyMember lisa = marge.haveChild("Lisa", Gender.FEMALE); 
System.out.println("Homer & Marge: " + marge + ", " 
    + marge.getPartner()); 
homer.splitUp(); 
FamilyMember dolores = 
    marge 
     .hookUpWith(new FamilyMember("New Guy", Gender.MALE)) 
     .haveChild("Dolores", Gender.FEMALE); 
FamilyMember bruno = 
    homer 
     .hookUpWith(new FamilyMember("New Girl", Gender.FEMALE)) 
     .haveChild("Bruno", Gender.MALE); 

System.out.println(
    "Marge & Partner: " + marge + ", " + marge.getPartner()); 
System.out.println("Marge's Ex-Partners: " + marge.getExPartners()); 
System.out.println(
    "Homer & Partner: " + homer + ", " + homer.getPartner()); 
System.out.println("Homer's Ex-Partners: " + homer.getExPartners()); 
System.out.println("Marge's kids: " + marge.getChildren()); 
System.out.println("Homer's kids: " + homer.getChildren()); 
System.out.println("Dolores's siblings: " + dolores.getSiblings()); 
System.out.println("Brunos's siblings: " + bruno.getSiblings()); 

Sortie:

Homer & Marge: [Marge, FEMALE], [Homer, MALE]
Marge & Partenaire: [Marge, FEMALE], [Nouveau type, MALE]
Marge's Ex -Partners: [[Homer, MALE]]
Homer & Partenaire: [Homer, MALE], [Nouvelle fille, femelle]
Ex-Partners Homer: [[Marge, FEMALE]]
enfants de Marge: [[Bart , MALE], [Lisa, FEMALE], [Dolores, FEMALE]]
Les enfants de Homer: [[Bart, MALE], [Lisa, FEMALE], [Bruno, MALE]]
Les frères et soeurs de Dolores: [[Bart, MALE ], [Lisa, Femme]]
frères et sœurs pour Brunos: [[Bart, MALE], [Lisa, FEMALE]]

Questions connexes