1

I am looking for a data structure to represent hierarchy class system in Java. For example, I have three class, University,Major,Student, and their relationship looks like below. enter image description here

Is there a efficient data structure that I can query with a path-like expression? For example, if the expression is CMU/cs/jake,then I get a instance of student class whose name is jake. As far as I know, the Trie could do this, is there any other option?

4
  • Are you looking for solutions in the Java API, or for quick "roll your own" suggestions? Commented Jun 11, 2015 at 3:16
  • The java collection do not provide this kind of DS, I am looking for a DS or any implementation suggestion. Commented Jun 11, 2015 at 3:19
  • It appears to me this is more about design pattern than data structure, abstract factory pattern might be what you are looking for Commented Jun 11, 2015 at 3:27
  • It's a general tree, but I don't know of any implementation that takes that kind of query expression. I agree with chiwangc it's more a design pattern than a data structure. I immediately read this as "CMU is a Map of ArrayList" so CMU.get("cs") returns an ArrayList<Student> so it's really Map<String, ArrayList<Student>> for example. Otherwise, you could process XML and XPath for that type of expression query capability. Commented Jun 11, 2015 at 4:46

1 Answer 1

1

If your data fits into memory then you can implement this by putting a Set of children in each node of the hierarchy and then walking the sets to determine if the path is valid, for example

class University {
  private Set<Major> majors;
}

class Major {
  private Set<Student> students;
}

class Main {
  // true if the path is valid, else false
  public boolean query(University university, Major major, Student student) {
    return university.getMajors().contains(major) &&
      major.getStudents().contains(student);
  }
}

If you also need to walk the reverse path (i.e. if you need a bidirectional hierarchy) then you can put a Set of parents in each child.

This will run in average case O(d) where d is the depth of the hierarchy if you use HashSets, and in worst case O(d * lg(n)) where n is the size of the sets if you use TreeSets.

If your data doesn't fit into memory then you may want to consider using a graph database, e.g. Neo4j.


Edit: You can make the code more generic at the cost of type safety by using Map<String, E> at each level, assuming that each object has a unique name or some other string identifier.

abstract class Hierarchical<E extends Hierarchical> {
  protected final Map<String, E> children;

  public boolean query(Queue<String> query) {
    String key = query.poll();
    if(key != null) {
      E value = map.get(key);
      if(value != null) {
        return query.isEmpty() || value.contains(query);
      }
    }
    return false;
  }
}

class University extends Hierarchical<Major> {}

class Major extends Hierarchical<Student> {}

// special case for the bottom of the hierarchy
class Student extends Hierarchical<Hierarchical> {
  public Student() {
    children = null;
  }

  @Override
  public boolean query(Queue<String> query) {
    throw new UnsupportedOperationException("query should never reach this depth");
  }
}

class Main {
  // true if the path is valid, else false
  public boolean query(Hierarchial root, Queue<String> query) {
    return root.contains(query);
  }
}

This has the same runtime depending on whether you use a HashMap or TreeMap. The query only consists of a queue of strings; at each level of the hierarchy the first string is removed, the Map is queried and the child node is returned if found, and the query proceeds on to the child node until the queue is empty (return true) or a node isn't found (return false).

Sign up to request clarification or add additional context in comments.

1 Comment

it is a workable solution,but when the level of tree grow the code will be very verbose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.