Zwei unbestimmte Objekte vergleichen...

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hi,

kennt jemand von Euch einen kürzere Alternative
um Objekte unbestimmten Typs zu vergleichen?
Es geht mir speziell um die "primitiven" Typen,
die speziel gecastet werden müssen.
Wichtig ist mir dabei, dass der Vergleich kein "Garbage" produziert.
Die übergebenen Objekte sind jeweils vom gleichen Typ.
Code:
  private static boolean compare(Object a, Object b)
  {
    if(a == null)
      return b==null;
    if(b == null)
      return false;

    // Kein Array, dann normal equals
    if(!a.getClass().isArray())
      return a.equals(b);
    else
    {
      // Sonst, wenn primitiver Typ
      if(a.getClass().getComponentType().isPrimitive())
      {
        // a ist "primitive", b nicht, raus mit false
        if(!b.getClass().getComponentType().isPrimitive())
          return false;
        if(a.getClass().getComponentType() == char.class)
          return Arrays.equals((char[])a, (char[])b);
        else if(a.getClass().getComponentType() == int.class)
          return Arrays.equals((int[])a, (int[])b);
        else if(a.getClass().getComponentType() == long.class)
          return Arrays.equals((long[])a, (long[])b);
        else if(a.getClass().getComponentType() == double.class)
          return Arrays.equals((double[])a, (double[])b);
        else if(a.getClass().getComponentType() == short.class)
          return Arrays.equals((short[])a, (short[])b);
        else if(a.getClass().getComponentType() == float.class)
          return Arrays.equals((float[])a, (float[])b);
        return false;
      }
      else
      {
        // b ist "primitive", a war's aber nicht, raus mit false
        if(b.getClass().getComponentType().isPrimitive())
          return false;
        // Object-Array, von welchem Typ auch immer
        return Arrays.equals((Object[])a, (Object[])b);  
      }
    }
  }
Gruß,
Michael
 
B

bygones

Gast
mhm - ich versteh zwar net den sinn und zweck der methode, aber wenn du schon die arrays miteinander vergleichst mach doch einfach:
Code:
public static boolean equals(Object[] a, Object[] a2)
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Arrays.html#equals(java.lang.Object[],%20java.lang.Object[])

In other words, the two arrays are equal if they contain the same elements in the same order. Also, two array references are considered equal if both are null.
 
G

Guest

Gast
Hi,

danke für die schnelle Antwort.
Das Problem ist eben, dass die übergebenen Objekte alles Mögliche sein können
aber jeweils zwei vom gleichen Typ (oder auch null).
z.B.

char[] a= new char[] {'a', 'b', 'c'};
char[] b= new char[] {'a', 'b'};
char[] c= null;
compare(a, b);
compare(a, c);

----
Integer a = new Integer(1);
Integer b = new Integer(2);
compare(a, b);

----
ComplexModel a = ...
ComplexModel b = ...
compare(a, b);

Sinn und Zweck des ganzen ist die equals Methoden komplexer Objekte
zu vereinfachen.
In einer equals Methode taucht dann für jedes Attribut folgendes auf:
Code:
  public boolean equals(Object o)
  {
    if(o==null || !(o instanceof SomeModel))
      return false;

    SomeModel m = (SomeModel)o;
    return compare(this.objectField, m.objectField)
        && compare(this.primitiveArray, m.primitiveArray)
        && (primitiveField == primitiveField)
        && usw;
  }
Dadurch spart man sich das ständige prüfen von "null" Werten etc.

Mir geht es nur um die "primitive" Arrays, ob es einen Weg gibt diese nicht
zu casten.
Ich möchte in den equals Methoden keine Unterscheidung machen, was für Daten
verglichen werden. Hauptsache der Vergleich liefert korrekte Ergebnisse.

Noch jemand mit Vorschlägen?
 

Isaac

Bekanntes Mitglied
Wenn du weist das die Objekte A und B vom gleichen Typ sind wieso überlädst du die compare Methode nicht einfach so oft wie du es brauchst?

Code:
    private static boolean compare(Object a, Object b)
    private static boolean compare(int i,int j)
    private static boolean compare(double i,double j)
    private static boolean compare(char i,char j)
    private static boolean compare(byte i,byte j)      
    private static boolean compare(long i,long j)

    und was auch immer....
 
G

Guest

Gast
Du hast recht, ist noch die beste Lösung.

Irgendwie ist die Typenprüfung von Java bescheuert.
Es ist möglich z.B. ein char[] als Objekt zu übergeben,
man kriegt daraus auch die Information, dass es ein
Array ist und die Elemente "primitive" und auch den Typen
der Elemente, dennoch gibt es keinen Sprachkonstrukt, diese
in ein Object-Array zu casten
(mit einer automagischen Konvertierung in den jeweiligen
Wrapper-Typen, hier Character).

OK, das war an sich kein Problem, nur den Code mit den vielen
if's fand ich ehmm.. uncool.
Außerdem wird jedes typ.class zu Class.forName("typ"), was
u.U. lamm sein kann, wenn man große Listen von Objekten
durchsucht.

Gruß,
Michael
 

Isaac

Bekanntes Mitglied
Mit 1.5 geht das. Aber sollte man, laut SUN sparsam verwenden. Ist auch eigentlich nicht wirklich nötig aber macht den Source Code wieder ein bischen schmaler.


Was hast du denn gegen das überladen der Methoden? Das ist der Weg den man eigentlich immer gehen sollte. Der Code ist schmal und wartungsfreundlich. Im gegensatz zu den "one for all" Methoden. Das war ja ein Grund wieso man diese Überladung irgendwann man als nützlich eingeführt hat.

Schau doch alleine mal System.out.println ich glaube die ist irgendwas bei 15fach überladen, ohne nun gezählt zu haben.
 

semi

Top Contributor
OK, jetzt geht's weiter mit meinem Nicknamen. Habe vorhin das Passwort vergessen :wink:

Klar, so habe ich es letztendlich auch gemacht (nur bei Arrays char[], int[] etc.),
nicht für die "primitive" Typen wie char, int etc.
Bei denen kann man auf den zusätzlichen Methodenaufruf verzichten (Klartext: a == b)

Es gibt noch zig andere Sachen, über die man sich in Java aufregen könnte
(z.B. die Implementierung von java.util.AbstractList.indexOf)

Angenommen man hat ein Objekt, welches über irgendeine Integer-ID identifizierbar
ist (oder auch PrimaryKey in EJB).
Code:
class A ...
{
  private Integer id;
  ...
}
Dazu eine equals-Methode, die auch die ID, also Integer, akzeptiert
Code:
  public boolean equals(Object o)
  {
    if(o==null)
      return false;
    if(o instanceof A)
    {
      Cast und normaler Vergleich für alle Attribute
    }
    // ID des Objektes mit dem gegebenen Integer vergleichen
    if(o instanceof Integer)
    {
      return id.intValue()==((Integer)o).intValue();
    }
    return false;
  }
Nun packt man zig Objekte vom Typ A in z.B. ein ArrayList
und möchte die Position des Objektes mit der ID = 1 holen.
Code:
int index = arrayList.indexOf(new Integer(1));
Funzt nicht, da die indexOf-Methode in AbstractList wie folgt implementiert ist.
Code:
    public int indexOf(Object o) {
	ListIterator e = listIterator();
	...
	    while (e.hasNext())
		if (o.equals(e.next()))
		    return e.previousIndex();
	}
	return -1;
    }
Der Vergleich entspricht also Integer.equals(A), was verständlicherweise immer scheitert.
Wäre der Vergleich umgekehrt,
Code:
e.next().equals(o)
dann könnte man durch eigene Implementierung der equals-Methode (wie oben)
selbst entscheiden, wann zwei Objekte gleich sind. Im Beispiel A.equals(Integer)
Auf die gleiche Art könnte man z.B. bei EJB schnell die Entity finden, die
in einer Liste lokaler Beans einen bestimmten Primary-Key hat.

Wie auch immer, genug gejammert :)

Gruß,
Michael
 

Isaac

Bekanntes Mitglied
Das hab ich nun nicht wirklich verstanden.

Object o und Object e sind doch sowieso vom gleichen Typ Die equals Methode der beiden Objekte sind also auch die gleichen und diese kannst du doch überschreiben. Beide implementierungen sollten doch dann auf das selbe hinausführen. Oder was bedenke ich dabei im Moment nicht?

Gruss,
Isa
 
G

Guest

Gast
Ich habe Vergleiche von Objekten gemeint, die unterschiedliche Typen haben.
Das folgende Beispiel verdeutlicht das "Problem".
Code:
public class Test
{
  public static void main(String argv[])
  {
    class Person
    {
      Integer id;
      String name;
      public Person(Integer id, String name)
      {
        this.id = id;
        this.name = name;
      }
      public boolean equals(Object o)
      {
        if(o == null)
          return false;
        if(o instanceof Person)
        {
          return this.id.equals(((Person)o).id);
        }
        // Hier der Vergleich der ID mit Integer 
        else if(o instanceof Integer)
        {
          return this.id.equals((Integer)o);
        }
        else 
          return false;
      }
    }

    Person p = new Person(new Integer(1), "Bart");
    System.out.println("Person.equals(Integer): " + p.equals(new Integer(1)));
    System.out.println("Integer.equals(Person): " + new Integer(1).equals(p));
  }
}
Dadurch, dass in AbstractList.indexOf(...) die zweite Variante ausgeführt wird,
kann man nicht Objekte mit unterschiedlichen Typen abfragen.
Stattdessen muss man selbst iterieren und über Getter die entsprechenden
ID's mit dem übergebenen Integer vergleichen.
Schau Dir mal die Implementierung von AbstractList.indexOf(...) an.
Es wird equals des übergebenen Objektes mit allen Elementen von
AbstractList verglichen.

OK, das ganze wird zu philosofisch. :)
Ma' kann da nix mache', ischt halt so.

Gruß,
Michael
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
D Zwei Listen vergleichen Allgemeine Java-Themen 7
Tobero Wie berechnet man ob zwei Linien sich schneiden? Allgemeine Java-Themen 2
kodela Zwei gleichzeitig gedrückte Steuertasten Allgemeine Java-Themen 10
X Bedingung zwei mal überprüfen Allgemeine Java-Themen 4
Zrebna Random Number - Generische Formel zwischen zwei INKLUSIVEN Werten Allgemeine Java-Themen 16
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
VfL_Freak Double mit zwei festen NK-Stellen ausgeben Allgemeine Java-Themen 9
Neoline Methoden Zwei Arrays abwechselnd zusammenführen Allgemeine Java-Themen 15
J Zwei Wavdateien gleichzeitig mit SourceDataLine abspielen Allgemeine Java-Themen 0
D Best Practice Die niedrigste Differenz zwischen zwei Listen ermitteln. Allgemeine Java-Themen 10
J Fahrroute zwischen zwei Punkten finden Allgemeine Java-Themen 1
J Kollision von zwei Kreisen Allgemeine Java-Themen 15
J Transfer von Integer zwischen zwei Clients - RMI Allgemeine Java-Themen 4
S Variablen split-Funkton mit zwei Variabeln verwenden? Allgemeine Java-Themen 4
T Alle Kombinationen aus zwei Arrays Allgemeine Java-Themen 8
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
AssELAss Zwei Arrays / ArrayLists inhaltlich vergleichen Allgemeine Java-Themen 2
H RegularExpression zwischen zwei Strings Allgemeine Java-Themen 2
P Zwei Applikationen mit einem Job Allgemeine Java-Themen 0
A Lineare Interpolation mit zwei Arrays Allgemeine Java-Themen 4
E Berechnung des Schnittpunktes von zwei Geraden Allgemeine Java-Themen 1
S Zwei String vergleichen, Fehler markieren Allgemeine Java-Themen 3
G Matrix reduzieren zwei Methoden Allgemeine Java-Themen 2
Dechasa Vergleichen von zwei Arrays Allgemeine Java-Themen 4
P Zwei ArrayLists: Ohne die eine überhaupt anzurühren, wird sie verändert Allgemeine Java-Themen 2
S Anwendung zum ausrechnen der Differenz von zwei Tagen Allgemeine Java-Themen 9
F Zwei LinkedHashMaps iterieren und vergleichen Allgemeine Java-Themen 2
M Zwei unterschiedliche JAR Dateien mit ANT erstellen Allgemeine Java-Themen 8
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
L Zwei Files miteinander vergleichen und Grafisch darstellen Allgemeine Java-Themen 1
T Zwei Wortendungen vergleichen ohne .equals Allgemeine Java-Themen 10
F Webstart zwei Java Versionen / aktivieren bzw deaktivieren Allgemeine Java-Themen 2
S Zwei Comparable (compareTo) vergleichen Allgemeine Java-Themen 6
E zwei Gleitkommazahlen durcheinander dividieren Allgemeine Java-Themen 2
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
turmaline OOP zwei gleiche Methoden mit kleinen Unterschieden Allgemeine Java-Themen 15
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
T Wie heißt ein Binärbaum, dessen Knoten immer zwei Kinder haben müssen? Allgemeine Java-Themen 2
C ActionListener zwei Buttons zuweisen Allgemeine Java-Themen 11
M Eclipse drei slashs durch zwei ersetzen? Allgemeine Java-Themen 3
1 zwei Strings vergleichen Allgemeine Java-Themen 16
C Buchstaben, die in zwei Wörtern vorkommen Allgemeine Java-Themen 13
J Gleiche Packagestruktur in zwei *.jar Dateien Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
B zwei-dimensionale Collections bzw. Array mit Indizes Allgemeine Java-Themen 3
C Zwei Arrays vereinen Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
N hashCode() für zwei ints Allgemeine Java-Themen 5
turmaline Gleichheit von zwei Maps Map <String, Map <String, String>> Allgemeine Java-Themen 30
N Wie Listenabgleich auf zwei CPU Cores auslagern? Allgemeine Java-Themen 6
D Zufall wahr bzw. falsch mit zwei Faktoren Allgemeine Java-Themen 10
H Datenaustausch zwischen zwei Java-Programmen Allgemeine Java-Themen 5
H Ausgabe von zwei Textfeldern Allgemeine Java-Themen 3
H Zwei unabhängige Threads miteinander kommunizieren lassen Allgemeine Java-Themen 3
G zwei mal synchronized Allgemeine Java-Themen 5
Z zwei Daten vergleichen Allgemeine Java-Themen 4
C ArrayList anhand von zwei Attributen sortieren Allgemeine Java-Themen 4
S Alle Elemente von zwei Listen vergleichen Allgemeine Java-Themen 10
T IText: Zwei A4 PDF´s auf ein A3 PDF´s Allgemeine Java-Themen 2
J Verschachtelte ListIteratoren um in zwei Listen hin und herzugehen Allgemeine Java-Themen 5
A Differenz zwischen zwei Uhrzeiten Allgemeine Java-Themen 7
H Shortcut ruft zwei Menu-punkte auf Allgemeine Java-Themen 5
J Zwei konstruktoren? Allgemeine Java-Themen 8
A zwei listen vergleichen und unterschiede anzeigen Allgemeine Java-Themen 3
J Zwei sortierte Listen zusammenfassen Allgemeine Java-Themen 8
G Linked List zwischen zwei Threds übergeben Allgemeine Java-Themen 11
J zwei HashMaps vereinen Allgemeine Java-Themen 3
C Viele Informationen aus zwei Collections vergleichen Allgemeine Java-Themen 2
G Jfreechart zwei charts Allgemeine Java-Themen 2
S Zwei Anwendungen unter Tomcat Allgemeine Java-Themen 4
T Anzahl Tage zwischen zwei Daten - Stunde fehlt? Allgemeine Java-Themen 2
V Zwei ArrayList(s) vergleichen Allgemeine Java-Themen 6
T Überprüfen ob zwei Farben ähnlich sind Allgemeine Java-Themen 14
M zwei main-Methoden Allgemeine Java-Themen 7
P zwei JFrames zusammenhängen Allgemeine Java-Themen 4
A Summe und Produkt von zwei Feldern ( arrays) Allgemeine Java-Themen 9
M HashMap kapselt zwei Objekte aber wie baut man eine Matrix? Allgemeine Java-Themen 2
H zwei Date Variablen überschreiben sich Allgemeine Java-Themen 2
2 Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 2
G Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 3
J Zwei String auf ähnlichkeiten untersuchen? Allgemeine Java-Themen 3
C kürzester weg zwischen zwei Punkten, Koordinaten finden Allgemeine Java-Themen 15
B zwei Bilder miteinander vergleichen Allgemeine Java-Themen 25
L Anzahl Tage zwischen zwei Kalenderdaten Allgemeine Java-Themen 5
P Threadprogrammierung - zwei Threads parallel - einer beendet Allgemeine Java-Themen 3
G Kommunikation von zwei Java-Programmen Allgemeine Java-Themen 3
A Zusammenfassen von zwei Dateien (wie beim DOS-Befehl copy) Allgemeine Java-Themen 6
S zwei Arrays zusammenfassen Allgemeine Java-Themen 14
L Zwei Hashtables statt einer? Allgemeine Java-Themen 6
M zwei Threads - ein singleton-Objekt Allgemeine Java-Themen 3
A funktion schiffeZeichnen zwei mal aufrufen Allgemeine Java-Themen 16
G zwei Rückgabewerte gefordert. Was tun ? Allgemeine Java-Themen 10
Chucky Zwei Binärbäume vereinigen Allgemeine Java-Themen 7

Ähnliche Java Themen

Neue Themen


Oben