繁体   English   中英

如何在 class 中为两个不同的任务在两个不同的构造函数中使用不同的初始化创建单个 HashMap 成员

[英]How to create a single HashMap member in a class for two different task with different initialization in two different constructors

为有向图创建了两个 HashMap(g1 和 g2),为无向图创建了另一个,但我想要一个声明 HashMap 并在各自的构造函数中进行不同的初始化。

class Graphs<T, V>{

    public HashMap<T, LinkedList<T>> g1;
    public boolean[] visited;
    public HashMap<T, LinkedList<Pair<T, V>>> g2;

    static class Pair<T, V>{
        public T edge;
        public V w;

        Pair(T  i, V j){
            edge = i;
            w = j;
        }

        public String toString(){
            return "(" +edge + "," + w+ ")";
        }
    }

    Graphs(int size){
        g1 = new HashMap<>();
        visited = new boolean[size +1];
    }

    Graphs(int size, boolean weight){
        g2 = new HashMap<>();
        visited = new boolean[size +1];
    }

    public void addEdges(T u , T v){
        if(!g1.containsKey(u)){
            g1.put(u, new LinkedList<>());
        }
        if(!g1.containsKey(v)){
            g1.put(v, new LinkedList<>());
        }
        g1.get(u).add(v);
        g1.get(v).add(u);
    }

    public void addEdges(T u , T v , V w){
        if(!g2.containsKey(u)){
            g2.put(u, new LinkedList<>());
        }
        if(!g2.containsKey(v)){
            g2.put(v, new LinkedList<>());
        }

        g2.get(u).add(new Graphs.Pair<T, V>(v, w));
        g2.get(v).add(new Graphs.Pair<T, V>(u, w));
    }
}

类应该按照 单一职责原则设计:它们应该只做一件事。

你有一个 class 正在做两件事。 因为这两个addEdges方法采用不同的参数(和不同数量的参数),并使用它们来创建不同的东西,所以这些类所做的两个“东西”之间几乎没有共同点,除了它们都表示图这一事实。

您也许可以设法在两个分离的类之间共享一些逻辑; 但是,老实说,这种设计比复制代码更糟糕。

class Graphs1<T>{

    public HashMap<T, LinkedList<T>> g1;
    public boolean[] visited;

    Graphs1(int size){
        g1 = new HashMap<>();
        visited = new boolean[size +1];
    }

    public void addEdges(T u , T v){
        g1.computeIfAbsent(u, k -> new LinkedList<>()).add(v);
        g1.computeIfAbsent(v, k -> new LinkedList<>()).add(u);
    }
}

class Graphs2<T, V>{

    public boolean[] visited;
    public HashMap<T, LinkedList<Pair<T, V>>> g2;

    // Pair declaration omitted.

    Graphs2(int size){
        g2 = new HashMap<>();
        visited = new boolean[size +1];
    }

    public void addEdges(T u , T v , V w){
        g2.computeIfAbsent(u, k -> new LinkedList<>()).add(new Graphs.Pair<>(v, w));
        g2.computeIfAbsent(v, k -> new LinkedList<>()).add(new Graphs.Pair<>(u, w));
    }
}

我想你可以声明一个 class 类似于:

class BaseGraph<T, E> {
  public HashMap<T, LinkedList<E>> g = new HashMap<>();
  public boolean[] visited;

  BaseGraph(int size) {
    this.visited = new boolean[size + 1];
  }

  protected void addEdge(T u, E value) {
    g.computeIfAbsent(u, k -> new LinkedList<>()).add(value);
  }
}

然后使它成为单独类中的成员:

class Graphs1<T> {
  BaseGraph<T, T> bg;

  Graphs1(int size) { bg = new BaseGraph<>(size); }

  public void addEdges(T u, T v) {
    bg.addEdge(u, v);
    bg.addEdge(v, u);
  }
}

class Graphs2<T, V> {
  BaseGraph<T, Pair<T, V>> bg;

  Graphs2(size) { bg = new BaseGraph<>(size); }

  public void addEdges(T u, T v) {
    bg.addEdge(u, new Pair<>(v, w));
    bg.addEdge(v, new Pair<>(u, w));
  }
}

我仍然不完全相信这比复制代码更值得。 它只真正节省了addEdge行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM