如何解决基于TXT文件的Java Person对象初始化依赖问题、索引关联错误及代码复杂度问题
Got it, let's tackle these three issues one by one with practical, maintainable fixes. Here's how to refactor your code and workflow:
1. Fix Object Initialization Order Constraints
The root issue here is that you're trying to link relationships while creating objects, which forces a strict parent-first order. The fix is to split initialization into two phases:
- Phase 1: Create all
Personobjects first, storing them in a map keyed by a unique identifier (like their name, assuming names are unique; if not, add a custom ID field to your file format). - Phase 2: Go back through each entry to establish parent-child, spouse relationships using the map to look up existing objects, regardless of their creation order.
Example Phase Implementation
// In MainClass, replace your run() method with this: public void run() { ArrayList<String> lines = null; try { lines = readFile("/persons.txt"); } catch (IOException | URISyntaxException e) { e.printStackTrace(); } // Phase 1: Create all persons and store in a map Map<String, Person> personMap = new HashMap<>(); for (String line : lines) { String[] parts = line.split("/"); Gender gender = Integer.parseInt(parts[0]) == 0 ? Gender.MAN : Gender.WOMAN; String name = parts[1]; Person p = new Person(name, gender); personMap.put(name, p); persons.add(p); // Keep the list if you still need it } // Phase 2: Establish relationships for (String line : lines) { String[] parts = line.split("/"); String name = parts[1]; Person current = personMap.get(name); // Set father if (!parts[2].equals("-")) { current.father = personMap.get(parts[2]); } // Set mother and child relationship if (!parts[3].equals("-")) { Person mother = personMap.get(parts[3]); current.mother = mother; mother.setChildFromMarriage(current); } // Set spouse if (!parts[4].equals("-")) { current.marryTo(personMap.get(parts[4])); } } }
2. Simplify TXT File Maintenance (Eliminate Index Shifts)
Instead of using numeric indexes (which break when lines are added/removed), use human-readable unique identifiers (like person names) in your TXT file. Your file format would look like this (use - to indicate no relationship):
0/John/-/-/Jane 1/Jane/-/-/John 0/Bob/John/Jane/- 1/Alice/John/Jane/-
This way, deleting a line (e.g., removing Alice's entry) doesn't require updating any other lines' references—all relationships are tied directly to names, not positions.
3. Reduce Code Complexity in String Parsing
Your original loadPerson method uses manual character-by-character parsing, which is error-prone and hard to read. Replace it with String.split("/") to split each line into an array of attributes in one line. This simplifies the code drastically and makes it easier to modify if you add new attributes later.
Optimized Parsing Logic
The code in the two-phase run() method above already uses this approach, but here's a standalone simplified version of the parsing step:
// Replace your old loadPerson method with this logic private Person parsePerson(String line) { String[] parts = line.split("/"); Gender gender = Integer.parseInt(parts[0]) == 0 ? Gender.MAN : Gender.WOMAN; String name = parts[1]; return new Person(name, gender); }
Bonus: Minor Java Best Practices
While you're refactoring, fix a few Java conventions to improve code readability:
- Rename
Nametoname(camelCase for instance variables) - Rename
childstochildren(correct pluralization) - Make instance variables private and add getters/setters (encapsulation)
Modified Person class snippet:
public class Person { private String name; private Gender gender; private Person father; private Person mother; private Person partner; private ArrayList<Person> children = new ArrayList<>(); // Enum and constructor remain similar, update to use name instead of Name public Person(String name, Gender gender){ this.name = name; this.gender = gender; } // Add getters like public String getName() { return name; } // ... rest of methods remain, update childs to children in setChildFromMarriage }
内容的提问来源于stack exchange,提问作者Hange Zoë

