0

2 つの jgraphT インスタンスを単純に等しくしようとしましたが、それらが同一であっても false を返します。次に、私の実装で equals をオーバーライドしようとしました。

public boolean equals(MyGraph<CustomV, CustomE> otherGraph){
    boolean result = true;

    Iterator<CustomV> vertexes = otherGraph.vertexSet().iterator();
    while(result && vertexes.hasNext()){
        result = this.containsVertex((V) vertexes.next());  
    }

    Iterator<CustomE> edges = otherGraph.edgeSet().iterator();
    while(result && edges.hasNext())
        result = this.containsEdge((E) edges.next());


    return result;
}

そして、そのエッジが EXACT オブジェクトでない場合、containsEdge() メソッドが失敗することがわかりました。エッジとスイッチの両方の equals メソッドをオーバーライドしたことを確認したため、これは奇妙です...

編集:この実験を行いました:

CustomV aNode = new CustomV(1,2);
myGraph.addVertex(aNode);
System.out.println(myGraph.containsVertex(aNode)); //true
System.out.println(myGraph.containsVertex(new CustomV(1,2))); //false..but should be true

ご覧のとおり、containsVertex() メソッドは機能していないようです。

edit2:愚かなフリークのおかげで、ほとんど解決しました: hashcode() メソッドもオーバーライドする必要がありました。現在、これは頂点では機能しましたが、エッジではハッシュコードで null ポインター例外が発生しました。これは私のオーバーライドされたメソッドです。

@Override
public int hashCode() {

    return (getSource().hashCode()+getTarget().hashcode());
}

グラフにエッジを作成しようとすると、null ポインターが返されます (ここで hashcode() が呼び出されると思います)。

myGraph.addEdge(a,b);

問題は、 getSource() と getTarget() がその瞬間に呼び出されたときに null を返すように見えることです...どうすれば解決できますか? これは例外スタックです:

スレッド「メイン」での例外 java.util.HashMap.hash(HashMap.java:366) での org.at.network.types.CustomE.hashCode(CustomE.java:71) での java.lang.NullPointerException。 org.jgrapht.graph.Abs​​tractBaseGraph.containsEdge(AbstractBaseGraph.java:359) で java.util.HashMap.containsKey(HashMap.java:453) で HashMap.getEntry(HashMap.java:466) org.jgrapht.graph.Abs​​tractBaseGraph でorg.jgrapht.graph.GraphDelegator.addEdge(GraphDelegator.java:131) の .addEdge(AbstractBaseGraph.java:208) org.jgrapht.graph.DefaultListenableGraph.addEdge(DefaultListenableGraph.java:162) の org.at.network。 types.MyGraph.addCustomEdge(MyGraph.java:27) at org.at.network.Test.main(Test.java:220)

addcustomedge メソッドは次のとおりです。

public CustomE addCustomEdge(V sourceVertex, Port sourcePort, 
        V targetVertex, Port targetPort){
    CustomE l = (CustomE)super.addEdge(sourceVertex, targetVertex);
    l.setSourceP(sourcePort);
    l.setTargetP(targetPort);

    return l;
}

ポートは、いくつかの文字列の単純なデータ構造です。

4

1 に答える 1

1

最初の問題に対する答え: Java で equals と hashCode をオーバーライドする

a.equals(b) の場合、a.hashCode() は b.hashCode() と同じでなければなりません

これは、ハッシュ ベースのデータ構造を使用する場合に特に重要です。要素はハッシュ コードに従ってバケットに配置され、同じバケット内の要素のみが を使用して比較されるためequals()です。


myGraph.addEdge(a,b);EdgeFactory(おそらく a )を使用してエッジを暗黙的に作成しますClassBasedEdgeFactory。の 206 行目以降を見てくださいAbstractBaseGraph。例外の発生元は次のとおりです。

E e = edgeFactory.createEdge(sourceVertex, targetVertex);

if (containsEdge(e)) { // this restriction should stay!

あなたが言ったように、デフォルトのコンストラクターを使用してエッジを構築します(ちなみに、頂点をまったく設定していないようです):

CustomE l = (CustomE)super.addEdge(sourceVertex, targetVertex);
l.setSourceP(sourcePort);
l.setTargetP(targetPort); 

つまり、エッジが によって使用されるcontainsEdge時点では、完全には初期化されていません! 通常、オブジェクトを完全に制御できないコードに公開する前に、オブジェクトを初期化する必要があります。初期化されていないオブジェクトを公開するときに発生する可能性のある多くの問題の 1 つを経験しました。特に、ソースとターゲットはまだハッシュベースのルックアップを実行しているため、次のコードnull:containsEdge

(getSource() == null? 0:getSource().hashCode())

をスローしNullPointerExceptionます。

この問題を解決するには、エッジを JGraphT API に渡す前に完全に初期化します。ソースとターゲットの頂点だけでなく、ポートも設定しているため、EdgeFactory.createEdge()には十分な情報がないようです。幸いなことに、オーバーロードされたメソッドがあるようGraph.addEdge(V sourceVertex, V targetVertex, E e)です。次のように使用することをお勧めします。

public CustomE addCustomEdge(V sourceVertex, Port sourcePort, 
        V targetVertex, Port targetPort){
    CustomE l = new CustomE(sourceVertex, sourcePort, targetVertex, targetPort);
    boolean added = addEdge(sourceVertex, targetVertex, l);
    if(added) return l;
    else return null;
}

もちろん、最初にそのCustomEコンストラクターを作成する必要があります。

于 2014-05-27T21:42:50.020 に答える