Gegenseitiger Ausschluss von XOR-Beziehung nur für Hinrichtung ausgeben

M

munzurOva

Gast
Hallo,

ich bekomme von einer Methode die Informationen, das sich bestimmte Einträge gegenseitig ausschließen (XOR). Diese gebe ich dann in Form einer Tabelle aus.
Ein Eintrag kann dabei auch zu mehreren Einträgen in einer XOR-Beziehung stehen.

Die Tabelle sieht folgendermaßen aus:
A - B // bedeutet: A XOR B
A - C
B - A // weil XOR bidirektional ist wir auch B XOR A ausgegeben.
C - A
D - E
D - F
E - D
F - D

Ich möchte jedoch nur die Hinrichtung und nicht ebenfalls die Rückrichtung in der Tabelle ausgeben, also wie folgt:
A - B
A - C // hier könnte auch C - A stehen.
D - E
D - F


Mein grober Code
Java:
String quelle, ziel;   //die quelle ist im obigen Beispiel A. Als Ziel hat A dann B  und C. 
Tabelle tabelle = new Tabelle();

for (...)   //solange  XOR-Beziehungen vorhanden sind
{
       quelle = getQuelle();    // 1. Durchlauf der Schleife liefert quelle=A. 2. Durchlauf der Schleife leifert quelle=A. 
       ziel = getZiel();          // 1. Durchlauf der Schleife liefert ziel=B. 2. Durchlauf der Schleife leifert ziel=C. 

       tabelle.ausgabeVonXOR(quelle, ziel);
}

Die Ausgabe der Tabelle in der jetzigen Form ist nicht das Problem. Mein Problem ist es in Zeile 10 der Methode "ausgabeVonXor()" nur die Hinrichtung der XOR-Bedingungen auszugeben.
Ich überlege ob man eine zusätliche String Variable zum Vergleich benutzen kann oder ein Boolean Flag. Jedoch weiss ich nicht wie.
Ich möchte vor Zeile 10 eine Abfrage haben, die dafür sorgt, dass nur die Hinrichtung der Methode übergeben werden soll. Für jede Denkhilfe wäre ich dankbar.
 

FArt

Top Contributor
Objektorientiert:
Man definiert ein Objekt "Tabelleneintrag" mit Quelle und Ziel als Attribut. Die equals-Methode liefert true, wenn die a.ziel == b.ziel && a.quelle == b.quelle || a.quelle == b.ziel && a.ziel == b.quelle sind.
Der Hashcode muss auch bei beiden Varianten gleich berechnet werden!
Dann liest man alle Zeilen ein, erstellt auf deren Basis jeweils einen Tabelleneintrag und stopft diese in ein Set, wenn so ein Eintrag noch nicht vorhanden ist. Schon hat mal alle disjunkten Einträge nach deinen Vorgaben.
 
M

munzurOva

Gast
Ich habe das mit :
--------
Man definiert ein Objekt "Tabelleneintrag" mit Quelle und Ziel als Attribut. Die equals-Methode liefert true, wenn die a.ziel == b.ziel && a.quelle == b.quelle || a.quelle == b.ziel && a.ziel == b.quelle sind.
--------
nicht ganz verstanden!


Es gibt gleich eine Hinrichtung bei mir, wenn ich diese Hinrichtung nicht hinbekomme :)
 

FArt

Top Contributor
Ich habe das mit :
--------
Man definiert ein Objekt "Tabelleneintrag" mit Quelle und Ziel als Attribut. Die equals-Methode liefert true, wenn die a.ziel == b.ziel && a.quelle == b.quelle || a.quelle == b.ziel && a.ziel == b.quelle sind.
--------
nicht ganz verstanden!


Es gibt gleich eine Hinrichtung bei mir, wenn ich diese Hinrichtung nicht hinbekomme :)

In Worten: zwei Einträge gelten als gleich, wenn Ziel und Quelle übereinstimmen, egal ob als Ziel oder als Quelle. Die Klasse muss also equals und hashCode passend überschreiben.
 

Andi_CH

Top Contributor
nicht ganz verstanden!

Es gibt gleich eine Hinrichtung bei mir, wenn ich diese Hinrichtung nicht hinbekomme :)

Das Spekatkel wird immer warscheinlicher :-(

Java:
public class Tabelleneintrag
{
	private String quelle = "";
	private String ziel = "";

	public void setQuelle(String pQuelle) { quelle = pQuelle; }
	public String getQuelle() { return quelle; }
	public void setZiel(String pZiel) { ziel = pZiel; }
	public String getZiel() { return ziel; }

	@Override
	public boolean equals(Object o) {
		Tabelleneintrag tmp = (Tabelleneintrag)o;
		return this.ziel == tmp.ziel && this.quelle == tmp.quelle ||
		       this.quelle == tmp.ziel && this.ziel == tmp.quelle;
	}
}
 

FArt

Top Contributor
@Andi_CH:
Ich hatte gehofft der TS kriegt das selber hin, nachdem der relevante Code ja schon jast in Java-Notation da stand ;-)

Aber eines fehlt bei dir noch: hashCode konsistent überschreiben. Es muss nämlich bei beiden Varianten der selbe rauskommen.... und die Klasse sollte immutable sein (Konstruktor rein, Setter raus), das ist immer vorzuziehen. Und mit Generics sparst du dir den Cast ;-)
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
Ich hab heute schon genug gelästert, da wollte ich mal konstruktiv sein ---- mit Grenzen natürlich :)

Ich hab da irgendwas verpasst wozu braucht es den Hashcode? (Ich hab aber das Problem auch nicht im Detail studiert)

Ich bin gespannt ob die "Hinrichtung" schon stattgefunden hat ;-)
 
M

munzurOva

Gast
entschuldigt meine verspätung (vorlesung) und mein unwissen. die hinrichtung wird gerade eingeleitet, nicht lange, dann wird mit der stuhl unter den füssen weggehauen :)

das ich das richtige verstehe:
1. ich muss eine neue Klasse bzw. Objekt "Tabelleneintrag" definieren
2. in dieser Klasse definiere ich zwei Attribute
3. die entsprechenden getter und setter Methoden
4. und eine equals methode ebenfalls in dieser Klasse;

Die Informationen, die ich erhalte übergebe ich an die setter-Methoden, wie folgt:
Java:
public class XOR
{

       Tabelleneintrag tabellenEintrag = new Tabelleneintrag();
       String quelle, ziel;   
       Tabelle tabelle = new Tabelle();
 
       for (...)   //solange  XOR-Beziehungen vorhanden sind
       {
              quelle = getQuelle();    // 1. Durchlauf der Schleife liefert quelle=A. 2. Durchlauf der Schleife leifert quelle=A. 
              ziel = getZiel();          // 1. Durchlauf der Schleife liefert ziel=B. 2. Durchlauf der Schleife leifert ziel=C. 
 
              tabellenEintrag.setQuelle(quelle);
              tabellenEintrag.setZiele(ziel);

              tabelle.ausgabeVonXOR(quelle, ziel);
       }
}

Meine Fragen (sorry aber ich blicke das nicht durch):
Und was fange ich jetzt mit der equals-Methode aus Tabelleneintrag an? Wo und wie verwende ich diese? Warum wird in der Klasse Tabelleneintrag folgendes definiert?
Java:
Tabelleneintrag tmp = (Tabelleneintrag)o;
 

FArt

Top Contributor
Ich hab heute schon genug gelästert, da wollte ich mal konstruktiv sein ---- mit Grenzen natürlich :)

Ich hab da irgendwas verpasst wozu braucht es den Hashcode? (Ich hab aber das Problem auch nicht im Detail studiert)

Ich bin gespannt ob die "Hinrichtung" schon stattgefunden hat ;-)

equals und hashCode müssen immer gleichzeitig und passend überschrieben werden: Object (Java 2 Platform SE v1.4.2)

Wenn bei obigem Beispiel hashCode nicht oder falsch überschrieben wird, würde das bedeuten, dass bei der Verwendung in einem HashSet ein "Duplikat", welches sich nur durch dir Richtung unterscheidet, nicht erkannt wird.
In einem Hashset (oder Map) werden die Einträge über den Hash als Schlüssel eingetragen. Ungleicher Hash kann dabei nicht gleich sein (=> schneller Ausschluss). Gleicher Hash kann gleich sein oder auch nicht... dann wird die equals-Methode bemüht.
 

Andi_CH

Top Contributor
entschuldigt meine verspätung (vorlesung) und mein unwissen. die hinrichtung wird gerade eingeleitet, nicht lange, dann wird mit der stuhl unter den füssen weggehauen :)

Und was fange ich jetzt mit der equals-Methode aus Tabelleneintrag an? Wo und wie verwende ich diese? Warum wird in der Klasse Tabelleneintrag folgendes definiert?
Java:
Tabelleneintrag tmp = (Tabelleneintrag)o;

Ein einfaches casting verstehst du nicht???:L???:L???:L
Binde dir schon mal ein weiches Kissen unter den Allerwertesten - dir fehlt zuviel!

Ausserdem solltest du die Klasse erst einmal um einen HashCode erweitern und vor allem Nutzen.

Zeige doch, dass du was konstruktives machst (mehr als nur drei wirre Zeilen Code in einer dubiosen XOR-Klasse - xor ist IMHO eine Methode und keine Klasse) dann rück ich schon noch etwas mehr raus ...
 
M

munzurOva

Gast
Ok, nach einigen recherschen habe ich mal den hashcode erweitert (kein gewährleistung auf korrektheit).
XOR sollte nur die beiden Klassen voneinander trennen. Ich nenne es dann lieber MeineKlasse :)

Java:
@Override
    public int hashCode()
    {
    	int result = 17; 
    	result = 31 * result + quelle.hashCode();
    	result = 31 * result + ziel.hashCode();
	return result;
    }

In MeinerKlasse rufe ich jetzt die equals Methode auf und erhalte ein ClassCastException:

Java:
public class MeineKlasse
{
 
       Tabelleneintrag tabellenEintrag = new Tabelleneintrag();
       String quelle, ziel;   
       Tabelle tabelle = new Tabelle();
 
       for (...)   //solange  XOR-Beziehungen vorhanden sind
       {
              quelle = getQuelle();    // 1. Durchlauf der Schleife liefert quelle=A. 2. Durchlauf der Schleife leifert quelle=A. 
              ziel = getZiel();          // 1. Durchlauf der Schleife liefert ziel=B. 2. Durchlauf der Schleife leifert ziel=C. 
 
              tabellenEintrag.setQuelle(quelle);
              tabellenEintrag.setZiele(ziel);
               
              if(tabellenEintrag.equals(quelle) == true)
              {
                     tabelle.ausgabeVonXOR(quelle, ziel);
              }
              if(tabellenEintrag.equals(quelle) == false)
              {
                     tabelle.ausgabeVonXOR(quelle, ziel);
              }
              if(tabellenEintrag.equals(ziel) == true)
              {
                     tabelle.ausgabeVonXOR(quelle, ziel);
              }
              if(tabellenEintrag.equals(ziel) == false)
              {
                     tabelle.ausgabeVonXOR(quelle, ziel);
              }
       }
}

In der Methode equals wird das Object o in Tabelleneintrag gecastet. Ich übergebe der equals Methode ein Parameter vom Typ String. Für gewöhnlich funktioniert das auch bei einer equals-Methode. Aber warum kann er hier kein Cast durchführen? Muss ich zudem alle möglichen If-Abfragen durchführen?

Ein weiches Kissen reicht nicht aus, es muss auch noch warm sein :)
 
M

munzurOva

Gast
ist ja auch klar das ich ein ClassCastException bekomme. Wie kann auch ein String eine Instanz von Tabelleneintrag sein?
deswegen war auch meine Frage, warum

Java:
Tabelleneintrag tmp = (Tabelleneintrag)o;

definiert wurde. Ich kann doch mein String nicht nach Tabelleneintrag casten oder sehe ich das falsch.
 
M

munzurOva

Gast
Hallo,

da ich am verzweifel bin, habei ich ein ausführbares Programm geschrieben, das mein Sachverhalt darstellen soll.
Eine kleine Hilfe bitte um die eigene Hinrichtung zu vermeiden :)

Tabelleneintrag mit den Input für die Hinrichtung. Wie gesagt, erfolgt der Cast in der equals-Methode nicht wie gewünscht. Zeile 71-73 wird nicht erreicht.
Java:
public class Tabelleneintrag {
	 private String quelle = "";
	 private String ziel = "";

	 String[] menge1 = {"A", "A", "B", "C", "D", "E"};
	 String[] menge2 = {"B", "C", "A", "A", "E", "D"};

	 OutputTable outputTable = new OutputTable();
	 
	 public static void main(String[] args)
	 {
		 Tabelleneintrag tabEintrag = new Tabelleneintrag();
		 tabEintrag.runMethod();
	 }
	 
	 public void runMethod()
	 {
		 Tabelleneintrag tabellenEintrag = new Tabelleneintrag();
		 for(int i=0; i<6; i++)
		 {
			 quelle = menge1[i];
			 ziel = menge1[i];
			 
			 tabellenEintrag.setQuelle(quelle);
			 tabellenEintrag.setQuelle(ziel);
			 
			 if(tabellenEintrag.equals(quelle) == true)
			 {
				 outputTable.ausgabeVonXor(quelle, ziel);
			 }
			 if(tabellenEintrag.equals(quelle) == false)
			 {
				 outputTable.ausgabeVonXor(quelle, ziel);
			 }
			 if(tabellenEintrag.equals(ziel) == true)
			 {
				 outputTable.ausgabeVonXor(quelle, ziel);
			 }
			 if(tabellenEintrag.equals(ziel) == false)
			 {
				 outputTable.ausgabeVonXor(quelle, ziel);
			 }
				 
		 }
	 }
	    
	 
	/**
	*Anstelle der setter-Methoden hätte ich auch ein Konstruktor verwenden können
	*Aber das spielt ja keine hier keine Rolle
	public Tabelleneintrag(String pQuelle, String pZiel)
	{
		quelle = pQuelle;
		ziel = pZiel;
	}
		 */
	
	public void setQuelle(String pQuelle) { quelle = pQuelle; }
    public String getQuelle() { return quelle; }
    public void setZiel(String pZiel) { ziel = pZiel; }
    public String getZiel() { return ziel; }
 
    @Override
    public boolean equals(Object o) {
    	if(!(o instanceof Tabelleneintrag))
    	{
    		System.out.println("Object ist keine Instanz von Tabelleneintrag");
    		return false;
    	}
        Tabelleneintrag tmp = (Tabelleneintrag)o;  // Object kann nicht nach Tabelleneintrag gecastet werden
        return this.ziel == tmp.ziel && this.quelle == tmp.quelle ||
               this.quelle == tmp.ziel && this.ziel == tmp.quelle;
    }

    @Override
    public int hashCode()
    {
        int result = 17; 
        result = 31 * result + quelle.hashCode();
        result = 31 * result + ziel.hashCode();
    return result;
    }
}


Ausgabe der Daten in einer JTable: Wenn die Zeile 15 auskommentiert und Zeile 16 auskommentiert wird, ist in der Tabelle die Hin- und Rückrichtung zu sehen. Momentan kriege ich in der ersten und zweiten Spalte nur ein E zu sehen.
Java:
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;


public class OutputTable {
	
	DefaultTableModel tabelModel;
	JTable jTable; 
	JFrame frame = new JFrame("Ausgabe der Hinrichtung");
	
	public void ausgabeVonXor(String firstColumn, String secondColumn)
	{
		String[][] row = {{firstColumn, secondColumn}};
//		String[][] row = {{"A", "B"}, {"A", "C"}, {"B", "A"}, {"C", "A"}, {"D", "E"}, {"E", "D"}};
		String[] column = {"Spalte1", "Spalte2"};
		
		tabelModel = new DefaultTableModel(row, column);
		jTable = new JTable(tabelModel);
		frame.add(new JScrollPane(jTable));
		frame.pack();
		frame.setVisible(true);
	}
}
 
M

munzurOva

Gast
Zeile 23 ist fehlerhaft:

geändert in:
Java:
ziel = menge2[i];
 
M

munzurOva

Gast
Ich habe jetzt die quell und ziel Variablen in entsprechende String Listen gepackt und übergebe dieser der Methode ausgabeVonXor(List<String> listQuelle, List<String> listZiel), siehe geänderten Code unten. Somit werden auch alle Einträge ausgegeben.

Es gibt nur noch zwei Fragen:
1. Was mache ich mit der überschriebenen equals-Methode, da diese kein cast durchführt?
2. Wie führe ich meine if-Abfragen durch? Wie folgt?
Java:
if(tabellenEintrag.equals(quelle) == false) // entsprechend alle 4 vier Möglichkeiten

oder

if(tabellenEintrag.equals(quelle) == tabellenEintrag.equals(ziel)) // entsprchend der anderen Möglichkeit

oder 

if(tabellenEintrag.equals(quelle) != tabellenEintrag.equals(ziel // entsprechend der anderen Möglichkeit


Java:
 public void runMethod()
	 {
		 Tabelleneintrag tabellenEintrag = new Tabelleneintrag();
		 List<String> listQuelle = new ArrayList<String>();
		 List<String> listZiel = new ArrayList<String>();
		 
		 for(int i=0; i<6; i++)
		 {
			 quelle = menge1[i];
			 ziel = menge2[i];
			 
			 tabellenEintrag.setQuelle(quelle);
			 tabellenEintrag.setQuelle(ziel);
			 listQuelle.add(quelle);
			 listZiel.add(ziel);
		 }

		 // TODO if-Abfragen bezgl. der equals-Methode definieren
	 }

Entsprechend hat sich auch die OutputTabelle geändert:
Java:
public void ausgabeVonXor(List<String> listQuelle, List<String> listZiel)
	{
		int sizeListQuelle = listQuelle.size();
		String[][] row = new String[sizeListQuelle][sizeListQuelle];
//		String[][] row = {{"A", "B"}, {"A", "C"}, {"B", "A"}, {"C", "A"}, {"D", "E"}, {"E", "D"}};
		String[] column = {"Spalte1", "Spalte2"};
		
		for(int i=0; i<sizeListQuelle; i++)
		{
			for(int j=0; j<2; j++)
			{
				if(j==0)
				{
					row[i][j] = listQuelle.get(i);
				}
				if(j==1)
				{
					row[i][j] = listZiel.get(i);
				}	
			}
		}
		
		tabelModel = new DefaultTableModel(row, column);
		jTable = new JTable(tabelModel);
		frame.add(new JScrollPane(jTable));
		frame.pack();
		frame.setVisible(true);
	}
 
M

munzurOva

Gast
Hallo,

können meine letzten 5 Beiträge gelöscht werden um den Überblick zu gewährleisten?

Die equals-Mehtode wurde mir vorgegeben. Die hashCode-Methode haber ich überschrieben.
Damit ihr ein lauffähiges Programm habt, habe ich alles auf das nötigste gekürzt.

Damit mein ursprüngliches Problem gelöst werden kann, soll die equals-Methode die Vergleiche durchführen und nur die Hinrichtung meiner Eingabe gewährleisten. Wird momentan folges ausgegeben:
A - B
A - C
B - A
C - A
D - E
E - D

so soll nur
A - B
A - C
D - E
ausgegeben werden. Leider kann ich mit der überschriebenen equals-Methode das nicht überprüfen.
Wie ich auch in anderen Themen und Internetseiten gelesen habe, erfolgt ein Cast von Object immer in dieser Art und Weise, wie dir mir zur Verfügung gestellten equals-Methode.

Ich übergebe in meinem Code der equals-Methode ein Parameter vom Typ String. Wenn String keine Instanz von Tabelleneintrag ist, so soll durch ein Cast dieses gewährleistet werden (Zeile 78 ). Jedoch kriege ich hier ein ClassCastException. Warum? Diese Vorgehensweise ist die gängigste die ich gelesen habe.

Ich bin wirklich am verzweifeln. Kann mir keiner weiterhelfen?


Hier mein Code (teilweise überarbeitet):
Java:
import java.util.ArrayList;
import java.util.List;


public class Tabelleneintrag {
	 private String quelle = "";
	 private String ziel = "";

	 String[] menge1 = {"A", "A", "B", "C", "D", "E"};
	 String[] menge2 = {"B", "C", "A", "A", "E", "D"};

	 OutputTable outputTable = new OutputTable();
	 
	 public static void main(String[] args)
	 {
		 Tabelleneintrag tabEintrag = new Tabelleneintrag();
		 tabEintrag.runMethod();
	 }
	 
	 public void runMethod()
	 {
		 Tabelleneintrag tabellenEintrag = new Tabelleneintrag();
		 List<String> listQuelle = new ArrayList<String>();
		 List<String> listZiel = new ArrayList<String>();
		 
		 for(int i=0; i<6; i++)
		 {
			 quelle = menge1[i];
			 ziel = menge2[i];
			 
			 tabellenEintrag.setQuelle(quelle);
			 tabellenEintrag.setQuelle(ziel);
			 listQuelle.add(quelle);
			 listZiel.add(ziel);
		 }

		 for(String q : listQuelle)
		 {
			 for(String z : listZiel)
			 {
				 if(tabellenEintrag.equals(q) == tabellenEintrag.equals(z))
				 {
					 System.out.println("quelle: " + q + ", ziel: " + z); // um den output zu verfolgen
					 outputTable.ausgabeVonXor(listQuelle, listZiel);
				 }
				 if(tabellenEintrag.equals(q) != tabellenEintrag.equals(z))
				 {
					 System.out.println("quelle1: " + q + ", ziel1: " + z); // um den output zu verfolgen
					 outputTable.ausgabeVonXor(listQuelle, listZiel);
				 }
			 }
		 } 
	 }
	    
	 
	/**
	*Anstelle der setter-Methoden hätte ich auch ein Konstruktor verwenden können
	*Aber das spielt ja keine hier keine Rolle
	public Tabelleneintrag(String pQuelle, String pZiel)
	{
		quelle = pQuelle;
		ziel = pZiel;
	}
		 */
	
	public void setQuelle(String pQuelle) { quelle = pQuelle; }
    public String getQuelle() { return quelle; }
    public void setZiel(String pZiel) { ziel = pZiel; }
    public String getZiel() { return ziel; }
    
    @Override
    public boolean equals(Object o) {
    	if(!(o instanceof Tabelleneintrag))
        {
            System.out.println("Object ist keine Instanz von Tabelleneintrag");
            return false;
        }
        Tabelleneintrag tmp = (Tabelleneintrag)o;  // Object kann nicht nach Tabelleneintrag gecastet werden
        return this.ziel == tmp.ziel && this.quelle == tmp.quelle ||
               this.quelle == tmp.ziel && this.ziel == tmp.quelle;
    }

    @Override
    public int hashCode()
    {
        int result = 17; 
        result = 31 * result + quelle.hashCode();
        result = 31 * result + ziel.hashCode();
    return result;
    }
}

Java:
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;


public class OutputTable {
	
	DefaultTableModel tabelModel;
	JTable jTable; 
	JFrame frame = new JFrame("Ausgabe der Hinrichtung");
	
	public void ausgabeVonXor(List<String> listQuelle, List<String> listZiel)
	{
		int sizeListQuelle = listQuelle.size();
		String[][] row = new String[sizeListQuelle][sizeListQuelle];
//		String[][] row = {{"A", "B"}, {"A", "C"}, {"B", "A"}, {"C", "A"}, {"D", "E"}, {"E", "D"}};
		String[] column = {"Spalte1", "Spalte2"};
		
		for(int i=0; i<sizeListQuelle; i++)
		{
			for(int j=0; j<2; j++)
			{
				if(j==0)
				{
					row[i][j] = listQuelle.get(i);
				}
				if(j==1)
				{
					row[i][j] = listZiel.get(i);
				}	
			}
		}
		
		tabelModel = new DefaultTableModel(row, column);
		jTable = new JTable(tabelModel);
		frame.add(new JScrollPane(jTable));
		frame.pack();
		frame.setVisible(true);
	}
}
 

FArt

Top Contributor
Java:
public class TabellenEintrag {

  private String quelle;

  private String ziel;

  public TabellenEintrag(String a, String b) {
    this.quelle = a;
    this.ziel = b;
  }

  public String getQuelle() {
    return quelle;
  }

  public String getZiel() {
    return ziel;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    TabellenEintrag that = (TabellenEintrag) o;

    return quelle.equals(that.quelle) && ziel.equals(that.ziel) || quelle.equals(that.ziel) && ziel.equals(that.quelle);
  }

  @Override
  public int hashCode() {
    int result = quelle.hashCode() + ziel.hashCode(); // gleich auch wenn Ziel und Quelle vertauscht sind!
    result = 31 * result;
    return result;
  }

  @Override
  public String toString() {
    return "TabellenEintrag{" +
        "quelle='" + quelle + '\'' +
        ", ziel='" + ziel + '\'' +
        '}';
  }

  public static void main(String[] args) {
    // Zum Test: VM mit -ea Starten; Das sollte in einen JUnit Test!!!
    final TabellenEintrag te1 = new TabellenEintrag("a", "b");
    final TabellenEintrag te2 = new TabellenEintrag("b", "a");
    assert te1.equals(te2);
    assert te1.hashCode() == te2.hashCode();

    final Set<TabellenEintrag> s = new HashSet<TabellenEintrag>();
    s.add(te1);
    s.add(te2);
    assert s.size() == 1;
  }
}
 

slawaweis

Bekanntes Mitglied
B - A // weil XOR bidirektional ist wir auch B XOR A ausgegeben.
was mich an der ganzen Sache interessiert ist, ob die Tabelle vollständig bidirektional ist, d.h. für jedes X - Y gibt es auch ein Y - X. Falls es noch eine Reihenfolge der Elemente gibt, könnte man es über ein simples if(A < B) { Ausgabe } machen. Das Anlegen von Caches in einem Programm mit sehr vielen Einträgen könnte zu anderen Problemen führen. Falls es ein Datenbankprogramm ist, sollte man solche Gruppierungen unbedingt über die SQL-Abfragen machen und keine Caches anlegen.

Slawa
 
M

munzurOva

Gast
erst mal vielen dank für die antwort.

ich habe noch immer nicht verstanden warum der cast vorher nicht funktioniert hat, aber mit deinem code es auf einmal funktioniert! Der Code war ja fast der gleiche!

Ist mit
Java:
 assert te1.equals(te2);
die Bedingung nicht erfüllt, dass die Objekte te1 und te2 gleich sind, weil Quelle und Ziel übereinstimmen, so wird die weitere Abarbeitung des Programms unterbrochen. Demzufolge müssen te1 und te2 in der nächsten Zeile die gleichen hasCodes haben.
Nun packst du die Objecte te1 und te2 in ein Set (vom Typ TabellenEintrag), damit doppelte bzw. gleiche Objekte nur ein mal auftauchen. Mit
Java:
 assert s.size() == 1;
überprüfst du die Bedingung, dass in dem Set mindestens zwei Elemente vorhanden sein müssen. Ist nur ein Element vorhanden, so soll die weitere Berechnung abgebrochen werden.

Soweit alles richtig verstanden?

Nun zwei Frage. Ich möchte ja der Klasse OutputTabelle die String-Parameter über die Methode ausgabeVonXor(String quelle, String ziel) übergeben. Aber mein Set ist vom Typ TabellenEintrag! Wie übergebe ich nun die Prameter quelle und ziel meiner Methode ausgabeVonXor? Muss ich vorher noch bestimmte if-Abfragen definieren?

PS: Die Tabelle ist vollständig bidirektional. Für jedes X-Y gibt es auch ein Y-X. Jedoch bekomme ich die Tabellen nicht über ein Datenbankprogramm.
 

FArt

Top Contributor
erst mal vielen dank für die antwort.

ich habe noch immer nicht verstanden warum der cast vorher nicht funktioniert hat, aber mit deinem code es auf einmal funktioniert! Der Code war ja fast der gleiche!

Tja, aber eben nur fast. Du hast den Grund herausgefunden, warum equals und hashCode immer gleichzeitig und konsistent überschrieben werden müssen.
Dein hashCode hat nicht zu equals gepasst. Die Methode wird dir übrigens nicht vorgegeben, die IDE schlägt nur eine Implementierung vor. In deinem Fall ist sie ... falsch. Dafür kann aber die IDE nichts, denn die kennt ja deinen Anforderungen nicht.

Mit den Asserts überprüfe ich nichts, sondern zeige dir, dass mit der von mir gezeigten Klasse deine Anforderungen erfüllt sind und das ganz funktioniert. Deswegen der Hinweis: pack das in einen JUnit Test, denn das ist eine wichtige Eigenschaft deiner Klasse TabellenEintrag.
 

Ähnliche Java Themen

Neue Themen


Oben