数据结构代表多对多的关系

时间:2015-07-19 07:02:57

标签: java data-structures collections

如果我们有学生和课程实体,并且他们之间的关系是多对多,即学生可以参加许多课程,许多学生可以参加课程。如果我们必须代表这种关系,那么我们可以通过哪种方式来表示这种关系。如果我们使用hashmap与学生作为关键和学生作为值的课程列表,那么我们需要另一个hashmap,通过它我们可以表示课程与学生的关系。是否有任何最佳方式来表示这种关系,以便快速搜索。

2 个答案:

答案 0 :(得分:4)

我认为使用数据结构的组合是合适的。这是一个小例子:

public class ManyToManyMap<S, C> {
    private Map<S, Set<C>> firstToSecondMap = new HashMap<>();

    private Map<C, Set<S>> secondToFirstMap = new HashMap<>();

    public void put(S first, C second) {
        if (!firstToSecondMap.containsKey(first)) {
            firstToSecondMap.put(first, new HashSet<>());
        }
        firstToSecondMap.get(first).add(second);

        if (!secondToFirstMap.containsKey(second)) {
            secondToFirstMap.put(second, new HashSet<>());
        }
        secondToFirstMap.get(second).add(first);
    }

    public Set<C> getFirst(S first) {
        return firstToSecondMap.get(first);
    }

    public Set<S> getSecond(C second) {
        return secondToFirstMap.get(second);
    }

    public Set<C> removeByFirst(S first) {
        Set<C> itemsToRemove = firstToSecondMap.remove(first);
        for (C item : itemsToRemove) {
            secondToFirstMap.get(item).remove(first);
        }

        return itemsToRemove;
    }

    public Set<S> removeBySecond(C second) {
        Set<S> itemsToRemove = secondToFirstMap.remove(second);
        for (S item : itemsToRemove) {
            firstToSecondMap.get(item).remove(second);
        }

        return itemsToRemove;
    }
}

以下是一个示例用法:

ManyToManyMap<String, String> mmMap = new ManyToManyMap<>();

mmMap.put("Tom", "Math");
mmMap.put("Tom", "Java");
mmMap.put("Tom", "Java");
mmMap.put("Mary", "Java");

Set<String> coursesByStudent = mmMap.getFirst("Tom"); // Java, Math
Set<String> studentByCourse = mmMap.getSecond("Java"); // Tom, Mary

mmMap.removeByFirst("Tom");
studentByCourse = mmMap.getSecond("Java"); // Mary

答案 1 :(得分:1)

双向图可用于实现多对多关系,其中每个节点可以连接到许多其他节点