0

As a follow-up to my now-closed question: Java Two-Way Linked Set data-structure. I have implemented a very naive interpretation of the data-structure I had described.

Here is a visual aid from the previous question:

enter image description here

Output:

Set<Object> set1 = s.get("C", RIGHT);
Set<Object> set2 = s.get(1, LEFT);

[2, 3, 4]
[A, B]

As you can see, I correctly retrieved the associated set for each query, but I am a little confused as to how I can implement my get() function to intelligently determined whether the user passed type U or T without the use of a flag.

Due to type erasure, I cannot do the following in my DoublyHashSet class:

public Set<U> get(T t) {
    return leftSet.get(t);
}

public Set<T> get(U u) {
    return rightSet.get(u);
}

I would think that those method signatures are different...


Code

DoublyHashSet.java

package Graph;

import java.util.Set;

public class DoublyHashSet<T, U> {
    public static final int LEFT = 0;
    public static final int RIGHT = 1;
    private NodeSet<T, U> leftSet;
    private NodeSet<U, T> rightSet;
    
    public DoublyHashSet() {
        leftSet  = new NodeSet<>();
        rightSet = new NodeSet<>();
        
        leftSet.setCompliment(rightSet);
        rightSet.setCompliment(leftSet);
    }

    public void add(T t, U u) {
        leftSet.add(t, u);
        rightSet.add(u, t);
    }
    
    public Set<Object> get(Object o, int side) {
        boolean value = (side & 1) == 0;
        
        if (value) {
            return (Set<Object>) leftSet.get((T) o);
        } else {
            return (Set<Object>) rightSet.get((U) o);
        }
    }
    
    public static void main(String[] args) {
        DoublyHashSet<Integer, String> s = new DoublyHashSet<Integer, String>();
        
        s.add(1, "A");
        s.add(1, "B");
        s.add(2, "A");
        s.add(2, "C");
        s.add(2, "D");
        s.add(3, "C");
        s.add(4, "C");
        
        Set<Object> set1 = s.get("C", RIGHT);
        Set<Object> set2 = s.get(1, LEFT);
        
        System.out.println(set1);
        System.out.println(set2);
    }
}

NodeSet.java

package Graph;

import java.util.HashSet;
import java.util.Set;

public class NodeSet<T, U> extends HashSet<Node<T, U>> {
    private static final long serialVersionUID = 1L;
    private NodeSet<U, T> compliment;

    public NodeSet() {
        this(null);
    }

    public NodeSet(NodeSet<U, T> compliment) {
        super();

        this.compliment = compliment;
    }

    public NodeSet<U, T> getCompliment() {
        return compliment;
    }

    public void setCompliment(NodeSet<U, T> compliment) {
        this.compliment = compliment;
    }

    public Node<T, U> find(T data) {
        for (Node<T, U> node : this) {
            if (node.getData() == data) {
                return node;
            }
        }

        return null;
    }

    public void add(T t, U u) {
        Node<T, U> tNode = find(t);
        Node<U, T> uNode = null;

        if (tNode == null) {
            tNode = new Node<T, U>(t);
        }

        if (compliment != null) {
            uNode = compliment.find(u);

            if (uNode == null) {
                uNode = new Node<U, T>(u);
            }
        }

        tNode.getConnections().add(uNode);
        this.add(tNode);
    }

    public Set<U> get(T t) {
        Set<U> set = null;
        Node<T, U> node = find(t);

        if (node != null) {
            set = new HashSet<U>();
            for (Node<U, T> connection : node.getConnections()) {
                if (connection != null)
                    set.add(connection.getData());
            }
        }

        return set;
    }
}

Node.java

package Graph;

import java.util.HashSet;
import java.util.Set;

public class Node<T, U> implements Comparable<Node<T, U>> {
    private T data;
    private Set<Node<U, T>> connections;

    public Node() {
        this(null);
    }

    public Node(T data) {
        this(data, new HashSet<Node<U, T>>());
    }
    
    public Node(T data, Set<Node<U, T>> connections) {
        this.data = data;
        this.connections = connections;
    }
    
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Set<Node<U, T>> getConnections() {
        return connections;
    }

    public void setConnections(Set<Node<U, T>> connections) {
        this.connections = connections;
    }

    @Override
    public int compareTo(Node<T, U> other) {
        return this.getData().toString().compareTo(other.getData().toString());
    }

    @Override
    public String toString() {
        return "Node [data=" + data + "]";
    }
}
Community
  • 1
  • 1
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 2
    You can't. Use different method names instead – ZhongYu Nov 15 '13 at 22:15
  • I know I can just write: `public Set getType1(T t) { return leftSet.get(t); }` and `public Set getType2(U u) { return rightSet.get(u); }`, now that I see it, if the types were the same, then this could cause a problem as to which set check? – Mr. Polywhirl Nov 15 '13 at 22:20

0 Answers0