简体   繁体   中英

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

Two HashMaps (g1 and g2) are created for the directed graph and another one for the undirected graph, but I want, with one declaration of HashMap and different initialization in their respective constructor.

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));
    }
}

Classes should be designed according to the single-responsibility principle : they should only do one thing.

You've got a class which is doing two things. Because the two addEdges methods take different parameters (and different numbers of parameters), and use those to create different things, there is little in common between the two "things" these classes do, beyond the fact they both represent graphs.

You could perhaps contrive to share some logic between two separated classes; but, honestly, the contrivance would be worse than just duplicating the code.

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));
    }
}

I suppose you could declare a class something like:

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);
  }
}

and then make this a member inside the separate classes:

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));
  }
}

I'm still not entirely convinced this is worthwhile over just duplicating the code. It only really saves on the addEdge lines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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