Vergleich zweier Objekte durch "Hashfunktion"

Boolesche

Mitglied
Ahoi Miteinander,

ich benötige eine Möglichkeit Eigenschaften zweier Objekte schnell zu vergleichen:
z.B.:

Objekt eins mit den Eigenschaften:
A = 12;
B = 0;
C = 123;
...

Objekt zwei mit den Eigenschaften:
A = 12;
B = 1;
C = 0;
...

Wenn man die Eigenschaften als "Füllstände" betrachtet, wäre meine Fragestellung zu dem Problem z.B. entsprechen die Füllstände von Objekt zwei mindestens dem von Objekt eins. (in dem Fall nein da: eins.C > zwei.C)

Da es sehr viele Eigenschaften gibt (>60) und eine Abarbeitung über Schleifen mühselig und Zeitaufwändig ist, hatte ich folgende Idee:

Alle Eigenschaften der Objekte in ein BitSet überführen und diese Sets zu vergleichen:

z.B. eins: 110001111011 zwei: 110010000000

Wichtig wäre auch die Information welche Eigenschaft nicht passt.

Ist dieser Ansatz sinnvoll, gibt es evtl. schon Hauslösungen in Java?

Beste Grüße
 

nrg

Top Contributor
welche datenhaltung hast du denn? BitSet klingt interessanter als es letzendlich ist.. da mach es in den meisten Fällen auch eine klasse mit einem boolean-array und paar methoden was auch meistens deutlich perfomanter ist.

edit: bei 'ner Map würde sich vllt sowas anbieten:

Java:
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class FillLevels {
	
	private Map<String, Integer> levels;
	
	public FillLevels() {
		this.levels = new HashMap<String, Integer>();
	}
	
	public void add(String name, int fillLevel) {
		levels.put(name, fillLevel);
	}
	
	public boolean atLeastThan(FillLevels fl) {
		for (Entry<String, Integer> e : levels.entrySet()) {
			Integer i = fl.levels.get(e.getKey());
			if (i != null && e.getValue() < i) return false;
		}
		return true;
	}
	
	public static void main(String[] args) {
		FillLevels fl1 = new FillLevels();
		fl1.add("A", 12);
		fl1.add("B", 0);
		fl1.add("C", 123);
		
		FillLevels fl2 = new FillLevels();
		fl2.add("A", 12);
		fl2.add("B", 1);
		fl2.add("C", 0);
		
		System.out.println(fl2.atLeastThan(fl1));
	}
}
 
Zuletzt bearbeitet:
B

bERt0r

Gast
Wie willst du Objekte mit hilfe eines Hash codes vergleichen, ausser auf gleichheit? Hash funktionen sind dafür ausgelegt, eben keinen Rückschluss auf die Inputdaten zu liefern.

Wenn du nur auf Gleichheit prüfen willst kannst du die equals Funktion deiner Objekte mit einer Hash-Funktion überschreiben, und die Hashwerte vergleichen.

Falls du für einen größer/kleiner Vergleich einfach nur die Summe deiner Eigenschaften vergleichen willst, kannst du die ja nochmal extra in deiner Klasse speichern, und bei jedem set neu berechnen. Dann kannst du schnell die zwei Summen vergleichen, ohne sie neu zu berechnen. Mit Hash hat das dann aber wie gesagt nix zu tun, und Objekt1(0,0,10) ist dann gleich groß wie Objekt2(5,5,0)
 

Ariol

Top Contributor
Wenn wir was über die Datenhaltung erfahren wirst du sicher konstruktivere Vorschläge bekommen.

z.B. für Arrays:
Java:
Arrays.equals(array1,array2);

Wo liegt überhaupt das Problem mit der Geschwindigkeit? 60 Objekte gegeneinander zu vergleichen sollte je nach Struktur kein Problem sein. Erst recht nicht wenn es sich um primitive Datentypen wie int, long, double, boolean usw. handelt.
 
B

bERt0r

Gast
@Ariol
Naja so ein equals wird intern doch auch über eine Schleife geregelt, und bei ein paar tausend Objekten mit ja 60 Vergleichen pro compare würde man die Performance schon merken. Bei kleineren Mengen hast du natürlich recht.
 

Ariol

Top Contributor
@Ariol
Naja so ein equals wird intern doch auch über eine Schleife geregelt, und bei ein paar tausend Objekten mit ja 60 Vergleichen pro compare würde man die Performance schon merken. Bei kleineren Mengen hast du natürlich recht.

Jop, es kommt eben auf den Anwendungsfall an. Solange vom Threadersteller nichts kommt bleibt wohl erstmal nir mutmaßen.

Eventuell ließe sich auch was mit Serialisierung machen, wobei dass sich bei 60 Objekten/Attributen/Werten wohl kaum lohnen wird.???:L
 

Boolesche

Mitglied
Vielen Dank für die schnellen Antworten!

Bilder sagen mehr als tausend Worte…ich habe mal ein Pseudo-UML mit einer Abstraktion des Konstruktes angefügt.

Ihr habt es schon vermutet es handelt sich um mehrere tausend Objekte -> um ein konkretes Beispiel zu nennen: EndObject bis 30k ZwischenObject mehrere hundert (siehe Anlage)…

Die Objekte sind in einer Art Baumstruktur hierarchisch geordnet: StammObjecte haben ZwischenObjecte und diese wiederum können EndObjecte aufnehmen. (Die original Baumstruktur ist noch etwas größer und verschachtelter).

  • Die Eigenschaften können ordinal, nominal Skaliert oder eben int/float sein.
  • Die EndObjekte werden über die die Methode addEndObject() eingefügt und dann nach unten weitergereicht wenn die Eigenschaften des Übergeordneten Objektes größer, oder gleich, etc. dem des Endobjektes sind und schließlich an das ZwischenObject gehängt. Wenn die Eigenschaften nicht passen, soll es nach Möglichkeit eine Info geben welche Eigenschaft der Engpass war (nur die Erste)

Die Idee (angelehnt an deinem Vorschlag nrg) wäre jetzt ein 2dimensionales Speicherkonstrukt zu nehmen (String, String) -> (Typ, Wert) dort alle Eigenschaften zu Speichern und dann über eine Schleife und einer Weiche wenn Typ X auftaucht einen cast des Wertes auf das eigentlichen Format vorzunehmen um anschließend die passende Vergleichsoperation vorzunehmen. Leider scheint mir dieser Ansatz wenig elegant, nur leider kann sich die Anzahl und Typen der Eigenschaften je nach Anwendungsfall unterscheiden…
 

Anhänge

  • pseudoUML.jpg
    pseudoUML.jpg
    69,3 KB · Aufrufe: 39

Ariol

Top Contributor
Hab jetzt grade keine solchen Datenmengen hier.
Hier eine Art DeepCompare zweier Objekte:
Java:
@SuppressWarnings({ "unchecked", "rawtypes" })
	public static int compare(Object o1, Object o2)
	{
		int result = 0;
		Field[] fields1 = o1.getClass().getDeclaredFields();
		for (int i = 0; i < fields1.length; i++)
		{
			Field f1 = fields1[i];
			System.out.println("Testing " + f1.getName());

			if (Modifier.isStatic(f1.getModifiers()))
			{
				System.out.println(" Field " + f1.getName() + " is static");
				continue;
			}

			Field f2 = null;
			try
			{
				f2 = o2.getClass().getDeclaredField(f1.getName());
			} catch (SecurityException e)
			{
				System.err.println(" Field " + f1.getName() + " not accessible");
				continue;
			} catch (NoSuchFieldException e)
			{
				System.err.println(" Field " + f1.getName() + " doesn't exist");
				continue;
			}

			if (!f1.isAccessible())
				f1.setAccessible(true);
			if (!f2.isAccessible())
				f2.setAccessible(true);

			Object v1, v2;
			try
			{
				v1 = f1.get(o1);
				v2 = f2.get(o2);
			} catch (Exception e)
			{
				System.err.println(" Getting value of field " + f1.getName() + " failed");
				continue;

			}

			if (v2 instanceof Comparable && v1 instanceof Comparable)
			{
				System.out.println(" Comparing " + v1 + " with " + v2);
				int compResult = ((Comparable) v1).compareTo(v2);

				if (compResult != 0)
					result = compResult;

				if (compResult == 1)
				{
					System.err.println("  Field " + f1.getName() + " is too low");
					break;
				} else
				{
					System.out.println("  Result was " + compResult);
				}
			} else
			{
				result=compare(v1, v2);
			}
			System.out.println("--------------------");
		}
		System.out.println("Compare finished with " + result);
		return result;
	}

Vielleicht hilft dir das ja...
Ist natürlich noch verbesserbar (Abfrage nach null, Hash-Vergleich, usw...) und die Debug-Ausgaben sind sicherlich auch etwas hinderlich, aber vielleicht hilft es dir ja auch so.

EDIT: v1 und v2 müssen auch auf null getestet werden!!!
 
Zuletzt bearbeitet:

Boolesche

Mitglied
Große Klasse dieses Forum! Danke Ariol ich werde deinen Ansatz am Wochenende in mein Modell einbauen. Auf die Idee die Objekte quasi nach ihren Variablen "zu fragen" bin ich überhaupt nicht gekommen...
 

Boolesche

Mitglied
Ahoi Miteinander,

es hat leider aus Zeitmangel etwas gedauert, nun habe ich eine Quick&Dirty Version erstellt, die soweit funktioniert. Im Grunde wird jetzt eine Attribut-Objekt erzeugt und diese mit zwei Strings befüllt. Dabei wird der Name in der entsprechenden HashMap durch ein korrespondierendes enum Objekt (mit den Infos zum Datenformat) ersetzt und der eigentliche Wert eingefügt. Bei Positivem Test zweier Objekte wird das Hauptobjekt mit neuen Werten befüllt, sonst eben nicht.
Performant ist das ganze irgendwie nicht dafür sehr flexibel, ich muss bei neuen Attributen lediglich die Enum-Klasse anpassen.

Habt Ihr Ideen wie man das ganze Testen und Vergleichen eleganter gestalten könnte?


Java:
import java.util.HashMap;
import java.util.Map.Entry;

public class RestrictionAttributes {
	
	HashMap<ObjektAttributes, String> restrMap;
	
	
	RestrictionAttributes(){
		restrMap = new HashMap<ObjektAttributes, String>();
	}
	
	
	public void checkFit(RestrictionAttributes restrA){
		
		HashMap<ObjektAttributes, String> map = new HashMap<ObjektAttributes, String>();
		boolean fit = true;
		
		for (Entry<ObjektAttributesObjektAttributes, String> e : restrMap.entrySet()) {
			
			String objA = restrA.restrMap.get(e.getKey());
			
			if(objA != null){
				
				String valueType = e.getKey().getValueType();
				
				//TODO unbedingt verbessern
				
				int result = 0;
				String newValue = "";
				
				if(valueType == "Integer"){
					
					result = Integer.parseInt(e.getValue()) - Integer.parseInt(objA);
					newValue = Integer.toString(result);
					
				} else if(valueType == "String"){

					result = ((Comparable) e.getValue()).compareTo(objA);
					newValue = e.getValue();
					
				} else if(valueType == "Float"){
					
					float flo = Float.parseFloat(e.getValue()) - Float.parseFloat(objA);
					newValue = Float.toString(flo);
					result = (int) Math.ceil(flo*10000);
					
				} else {
					System.out.println("Unbekanntes Format");
				}
				
				if(result < 0){
					System.out.println(e.getKey()+" zu klein");
					fit = false;
					//TODO Fehlerliste fuellen
				} else {
					System.out.println("easy");
					map.put(e.getKey(), newValue);
				}

			}
        }
		
		if(fit != false){
			updateRestiction(map);
			System.out.println("Update Restriction");
		}
	}
	
	
	
	public void updateRestiction(HashMap<ObjektAttributesObjektAttributes, String> map){
		
		for (Entry<ObjektAttributesObjektAttributes, String> e : map.entrySet()) {
			restrMap.put(e.getKey(), e.getValue());
		}
	}
	
	public void setRestriction(String name, String value){
			
		ObjektAttributesObjektAttributes[] attr = ObjektAttributesObjektAttributes.values();
		
		for (ObjektAttributesObjektAttributes staAtt : attr) {
			if(staAtt.getName() == name){
				restrMap.put(staAtt, value);
				break;
			}
		}
		
		
	}
	
	public void ausgabe(){
		for (Entry<ObjektAttributesObjektAttributes, String> e : restrMap.entrySet()) {
			System.out.println(e.toString());
		}
		
	}
	
	// Test
	public static void main(String[] args) {
		
		RestrictionAttributes tes1 = new RestrictionAttributes();
		tes1.setRestriction("name", "tester");
		tes1.setRestriction("number", "12");
		tes1.setRestriction("height", "1.6");
		tes1.setRestriction("rotation", "1.6");
		
		RestrictionAttributes tes2 = new RestrictionAttributes();
		tes2.setRestriction("name", "tester");
		tes2.setRestriction("number", "10");
		tes2.setRestriction("height", "1.0");

		tes1.checkFit(tes2);
		tes1.ausgabe();
	}
	

}

Java:
public enum ObjektAttributes {
	
	  NAME("name", "String"), 
	  NUMBER("number", "Integer"),
	  ROTATION("rotation", "String"), 
	  HEIGHT("height", "Float");
	  
	  private String valueType;
	  private String name;

	  private ObjektAttributes(String name, String valueType){
		  this.valueType = valueType;
		  this.name = name;
	  }
	  
	  public String getName(){
		  return name;
	  }
	  
	  public String getValueType(){
		  return valueType;
	  }
	  
}
 
S

SlaterB

Gast
muss man das vorherige alles gelesen haben? erkläre doch worum es geht, was die Aufgabe von checkFit usw. ist,

Strings mit == zu vergleichen ist immer schlecht, wobei bei Enum das gerade so schön leicht geht und du verzichtest draus,
schreibe doch

Java:
ObjektAttributesObjektAttributes key = ..;
if (key == ObjektAttributesObjektAttributes.NUMBER) {
} else..

oder noch besser:
switch (key) {
  case NUMBER:
  ..

  ..
  default: unknown
}
 

Boolesche

Mitglied
Nein muss man nicht. Es geht im Kern darum eine flexible Möglichkeit Attribute verschiedener Objekte miteinander zu vergleichen zu können:

-> Objekt1.checkFit(Objekt2): Es soll getestet werden ob Objekt das Objekt2 aufnehmen kann, daher ob die Restriktionen (Objekt1.Restriktionen - Objekt2.Restriktionen = Neue Objekt1.Restriktionen) >0 oder bei String = sind

-> updateRestiction(): Wenn die Prüfung aus checkFit() erfolgreich war daher fit = true, wird diese Methode ausgeführt und die Änderungen bzw. neuen Werte für Objekt1 geupdated.

-> setRestriction(): Füllt die Restriktionen der Objekte ganz zu Anfang
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Vergleich zweier Objekte in einer HashMap Java Basics - Anfänger-Themen 6
S Vergleich zweier ArrayLists mit Ausgabe an dritte ArrayList Java Basics - Anfänger-Themen 5
G Klassen Vergleich zweier Klassen Java Basics - Anfänger-Themen 23
L Vergleich zweier Variablen, mit Abweichung Java Basics - Anfänger-Themen 3
N Methoden Methode zum Vergleich zweier Geburtstage Java Basics - Anfänger-Themen 5
M Vergleich zweier Array Stellen mit equals/NullpointerException Java Basics - Anfänger-Themen 9
N Vergleich zweier String Arrays scheitert Java Basics - Anfänger-Themen 3
L vergleich zweier texte Java Basics - Anfänger-Themen 18
G Vergleich zweier Arrays Java Basics - Anfänger-Themen 8
N Vergleich zweier Elemente verschiedener Vectoren Java Basics - Anfänger-Themen 2
G Vergleich zweier 'long'-Werte. Problem! Java Basics - Anfänger-Themen 6
heinrich172 Methoden Trotz gleichem Element stimmt Vergleich nicht? Java Basics - Anfänger-Themen 7
U Interface als PAramter (Vergleich) und ein Error Java Basics - Anfänger-Themen 9
K Erste Schritte Wie schnell ist LinkedHashMap im Vergleich zur ArrayList, wenn alle Entries durchlaufen werden? Java Basics - Anfänger-Themen 47
B Performance-Vergleich mit C++ Java Basics - Anfänger-Themen 55
K Rekursiver Vergleich von Textmuster und Text Java Basics - Anfänger-Themen 2
Zeppi Vergleich von Array-Inhalten Java Basics - Anfänger-Themen 14
Lena_2611 Vergleich von Array1 Index mit Array2 Wert und erzeugen eines neues Arrays Java Basics - Anfänger-Themen 8
B Date - Vergleich (equals / after) ? Java Basics - Anfänger-Themen 3
J Problem beim vergleich von zwei Integer Java Basics - Anfänger-Themen 3
W Vergleich von DatenPaketen Java Basics - Anfänger-Themen 6
B String vergleich Java Basics - Anfänger-Themen 3
C Probleme mit String-Vergleich Java Basics - Anfänger-Themen 4
K File-Name Vergleich Java Basics - Anfänger-Themen 2
V Fließkommazahlen Vergleich Java Basics - Anfänger-Themen 7
J Vergleich Java Basics - Anfänger-Themen 2
N Vergleich von Strings schlägt fehl.. Java Basics - Anfänger-Themen 5
T Vergleich und Ausgabe von Zahlen Java Basics - Anfänger-Themen 1
J Fehler bei Vergleich auf den grössten Wert Java Basics - Anfänger-Themen 2
A Do-While Schleife; int vergleich Java Basics - Anfänger-Themen 2
G Wieviel kostet der Zugriff auf Objektattribute im Vergleich zur Erstellung von vars in Methode? Java Basics - Anfänger-Themen 11
T Input/Output String-Vergleich schlägt fehl Java Basics - Anfänger-Themen 7
W Konvertierung und Vergleich unterschiedlicher Zeitformate Java Basics - Anfänger-Themen 11
W Vergleich mit If-Abfrage nur für Zahlen bis 07 möglich - Warum? Java Basics - Anfänger-Themen 7
M String-Vergleich und NullPointerException Java Basics - Anfänger-Themen 4
L PW-Vergleich Java Basics - Anfänger-Themen 5
S Vergleich von Listen Java Basics - Anfänger-Themen 6
J vergleich von arrays (benötige Hilfe/Denkanstoß) Java Basics - Anfänger-Themen 16
V Einfacher vergleich von Arrays geht schief Java Basics - Anfänger-Themen 2
T Operatoren Multiplikation nur mit Addition, Subtraktion und Vergleich Java Basics - Anfänger-Themen 29
N Methoden Array vergleich funzt nicht Java Basics - Anfänger-Themen 8
B Char-Vergleich Sonderzeichen Java Basics - Anfänger-Themen 6
S Vergleichsmethode zum Objekt-Vergleich mit < und > Java Basics - Anfänger-Themen 4
F Problem bei Vergleich Java Basics - Anfänger-Themen 3
S File vergleich - Junit Java Basics - Anfänger-Themen 6
P String-Vergleich Java Basics - Anfänger-Themen 3
S Multiplikation durch Addition, Subtraktion und Vergleich von Zahlen Java Basics - Anfänger-Themen 14
W Vergleich ob Buchstabe in einem Wort enthalten ist Java Basics - Anfänger-Themen 3
C String Objekte Vergleich je nach Instanzierung unterschiedlich!!?!! Java Basics - Anfänger-Themen 4
R String-Vergleich Java Basics - Anfänger-Themen 15
C Variablen Vergleich funktioniert nicht Java Basics - Anfänger-Themen 11
J Erste Schritte Vergleich der String-Objekte Java Basics - Anfänger-Themen 17
B Zwei verschiedene Daten vergleich Java Basics - Anfänger-Themen 2
A Variablen Vergleich Java Basics - Anfänger-Themen 5
P Erste Schritte vergleich substring und string Java Basics - Anfänger-Themen 4
G Date - Calender | "Vergleich" Java Basics - Anfänger-Themen 3
M Vergleich mit Toleranz Java Basics - Anfänger-Themen 7
B Objekt Vergleich - Unterschiede ausgeben Java Basics - Anfänger-Themen 4
P Vergleich mit Variablen Java Basics - Anfänger-Themen 6
Y Java Programm URL und String Vergleich! Java Basics - Anfänger-Themen 4
K Vergleich von variable und array Java Basics - Anfänger-Themen 9
H Beim Vergleich/Sortieren mehr als zwei Objekte berücksichtigen Java Basics - Anfänger-Themen 14
P Vergleich von Enums Java Basics - Anfänger-Themen 4
S String Vergleich funktioniert nicht Java Basics - Anfänger-Themen 3
A String-Vergleich geht nicht Java Basics - Anfänger-Themen 2
U Automatenprüfung in Java implementieren — String Vergleich klappt nicht Java Basics - Anfänger-Themen 40
F Methoden Vergleich von int Zahlen Java Basics - Anfänger-Themen 16
F Login Passwort-Vergleich Java Basics - Anfänger-Themen 12
N Vergleich per equals Java Basics - Anfänger-Themen 5
Z XML Vergleich Java Basics - Anfänger-Themen 20
S Herunterladen von Dateien mit Vergleich Java Basics - Anfänger-Themen 6
L Problem String-Vergleich Java Basics - Anfänger-Themen 2
E Objekte-Vergleich Java Basics - Anfänger-Themen 6
Y Datentypen String vergleich Java Basics - Anfänger-Themen 3
R Vergleich von Objekten anhand variierender Kriterien Java Basics - Anfänger-Themen 5
K Datentypen Arrays in Java - Adress-Arithmetik im Vergleich zu Listen Java Basics - Anfänger-Themen 4
S equals vergleich Java Basics - Anfänger-Themen 10
A Datentypen instanceof VS Class - Vergleich Java Basics - Anfänger-Themen 4
M Char vergleich zu Int Java Basics - Anfänger-Themen 10
G Wann ist ein == Vergleich bei Gleitkommazahlen fahrlässig? Java Basics - Anfänger-Themen 8
algorismi Ausführungszeit Vergleich == true Java Basics - Anfänger-Themen 8
J Performance Vergleich von if-Abfragen mit mehreren Bedingungen Java Basics - Anfänger-Themen 9
T Zwei listen vergleich und selbige löschen Java Basics - Anfänger-Themen 4
T Vergleich mit Typecasts Java Basics - Anfänger-Themen 3
Screen Eine Frage zu moueMove in applets und deren Vergleich Java Basics - Anfänger-Themen 11
M Vergleich Float-, Doublewert Java Basics - Anfänger-Themen 10
U Methode Vergleich von 2 Arrays Java Basics - Anfänger-Themen 5
S String Vergleich mit Passwort geht nur bei Zahlen ? Java Basics - Anfänger-Themen 7
G Vergleich klappt nicht Java Basics - Anfänger-Themen 3
T Vergleich von generischen Typen Java Basics - Anfänger-Themen 2
C DB Vergleich mit Eingabe Java Basics - Anfänger-Themen 5
G Vergleich großer Basen/Exponenten? Java Basics - Anfänger-Themen 3
F Vergleich von Objekten Java Basics - Anfänger-Themen 2
N Vergleich findet nicht statt. Java Basics - Anfänger-Themen 13
M 2 Fragen: Vergleich, aber wie? Was passiert in diesem Teil? Java Basics - Anfänger-Themen 18
A Vergleich schlägt fehl Java Basics - Anfänger-Themen 15
G Vergleich bei MD5-Verschlüsselung Java Basics - Anfänger-Themen 3
R +1 Vergleich Java Basics - Anfänger-Themen 3
E Char vergleich Java Basics - Anfänger-Themen 7
loadbrain Array vergleich mit 2 for schleifen Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben