Null Pointer in der compare-Methode des Comparators?

Status
Nicht offen für weitere Antworten.

Jay1980

Bekanntes Mitglied
Servus,

das kapiere ich gerade nicht.

Ich bekomme einen Null Pointer in der compare-Methode einer inneren Klasse als Comparator - wie geht das, denn ich kann die Methode doch nur aufrufen, wenn ich die beiden zu vergleichenden Objekte mitschicke?

Beim Zugriff auf u1 oder u2 krachts - mal so mal so?!

Java:
// Baum der die Umkreise vorhaelt
		umkreisBaum = new TreeSet<Umkreis>( new Comparator<Umkreis>(){
			@Override
			public int compare( Umkreis u1, Umkreis u2 )
			{
				// Comparator
				// Umkreise werden nach deren Radius in den Baum eingeordnet. 
				// Hier reicht der Radiusvergleichswert eines Kreises, um die Ordnung zu 
				// erstellen und der Winkelvergleichswert um zu testen, ob der Winkel 
				// des ersten kleiner als der Winkel des groesseren Kreises ist. Spaeter 
				// kann man mit der Winkelvergleichszahl auch errechnen. ob der Winkel 
				// kleiner gleich 90 Grad ist.
				// Der groesste Umkreis liegt oben im Baum und wird als uTop gegriffen.
				
				// Ganzzahlvariante
				//System.out.println("KleinsterKreis - Baum mit Umkreisen anlegen - vergleichen von ");
				//System.out.println("U1-a: " + u1.a.xWert + "; "+ u1.a.yWert + "| U1-b: " + u1.b.xWert + "; " + u1.b.yWert + "| U1-c: " + u1.c.xWert + "; " + u1.c.yWert + "|");
				//System.out.println("U2-a: " + u2.a.xWert + "; "+ u2.a.yWert + "| U2-b: " + u2.b.xWert + "; " + u2.b.yWert + "| U2-c: " + u2.c.xWert + "; " + u2.c.yWert + "|");
				
				// TODO durchdenken ob hier nicht double besser waere und was beim Cast schiefgehen kann
				
				System.out.println( "KleinsterKreis - compare() - im Vergleich ");
				System.out.println( " --> u1 mit a: " + u1.a.toString() + " b: " + u1.b.toString() + " c: " + u1.c.toString() + " wvw:" + u1.winkelVergleichsWert );
				System.out.println( " --> u2 mit a: " + u2.a.toString() + " b: " + u2.b.toString() + " c: " + u2.c.toString() + " wvw:" + u2.winkelVergleichsWert );
				
				int erg = u1.istRadiusKleinerAlsVergleichsUmkreis(u2);
				
				if ( erg == 1 )
				{
					// u1 groesser als u2
					//System.out.println(" --> Kreis U1 groesser als U2.");
					return 1; 
				}
......
 
Zuletzt bearbeitet:
wie geht das, denn ich kann die Methode doch nur aufrufen, wenn ich die beiden zu vergleichenden Objekte mitschicke?
Du kannst auch
Code:
null
"mitschicken"...

im welchen Zusammenhang steht der Code, von was wird die compare-Methode (indirekt?) aufgerufen?
 
Oh, das wusste ich nicht, dass ich/Java null mitschicken kann.

Die Methode wird von einem TreeSet aufgerufen, es haelt Umkreis-Objekte ja immer geordnet vor - das heisst, wenn ich nen neuen Umkreis anlege, muessen eigentlich alle mal durchgegangen werden. Allerdings weiss ich nicht, wie das Java intern regelt - ich sehe eben nur meine Ausnahme. Muss da mal was (für mich neues) überlegen - oder habt ihr bei sowas eine bewährte Herangehensweise?
 
überprüf halt in deiner public int compare( Umkreis u1, Umkreis u2 )
MEthode ob u1 oder u2 null sind...
 
ich würd so was an den Anfang der Methode schreiben:
Java:
if (u1 == u2) {
    return 0;
}
if (u1 == null || u2 == null) {
    return u1 == null ? 1 : -1;
}
[...]
 
ich würd so was an den Anfang der Methode schreiben:
Java:
if (u1 == u2) {
    return 0;
}
if (u1 == null || u2 == null) {
    return u1 == null ? 1 : -1;
}
[...]
Java:
if (u1 == null || u2 == null) {
 return 1;
}
warum noch die andere vgl ? wenn eins null ist wuerde ich sagen ist eine ordnung nicht definiert, also beliebig
 
warum noch die andere vgl ? wenn eins null ist wuerde ich sagen ist eine ordnung nicht definiert, also beliebig

ist A > null -> 1
ist null > A -> 1

ich weiß nicht ob das nicht zu Problemen führt...

Wenn du jetzt eine Liste sortierst, brauchen die null Elemente auch eine Ordnung.. entweder an erster oder letzer stelle.. so könnte ja eine zufällige Ergebnis, je nach dem wie du vergleichst, raus kommen...
 
Mir ist die potentiell doppelte Abfrage von u1==null aufgefallen 😉 habe aber erstmal nichts dazu gesagt... vielleicht also so
Code:
if (u1 == u2) 
{
    return 0;
}
if (u1 == null)
{
    return 1;
}
if (u2 == null) 
{
    return -1;
}
 
null kann in einer Liste sein.
Eine Liste kann man soriteren.
Somit sollte das Verhalten definiert werden, wenn null drin ist...

dennoch hat tfa's einwand schon berechtigung... was macht null in einer Liste ? riecht eher nach fehler als nach intension

wie auch immer.

ist hier ne allgemeine diskussion ob null eine Ordnung hat bzw wie steht null zu einem ex. Objekt und unterscheidet sich wenn objekt a null ist oder objekt b null ist ?
 
Marco13, naja in diesem Fall zieh ich Schönheit der Geschwindigkeit vor.

Ich auch 🙂 Deswegen finde ich es auch intuitiver, hinzuschreiben, was gemacht wird:
Wenn sie gleich sind, sind sie gleich
Wenn das erste null ist, ist das zweite größer
Wenn das zweite null ist, ist das erste größer

Was du geschrieben hattest war ja: Wenn eines von beiden null ist, dann ist das zweite größer, wenn das erste null ist, und das erste ist größer, wenn das erste nicht null ist...

Aber das ist vielleicht Ansichts- oder Geschmacksache.
 
OK, bygones war schneller.

muaaahhhhhh
128774370214267721.jpg


🙂
 
Zurueck zum Thema, ich habe einen Konstruktor in der ein Comparator als innere Klasse ist. Jetzt bekomme ich eine Ausnahme wenn ich den ersten Umkreis erzeuge fürs TreeSet, weil ja dabei das zweite Objekt fehlt, es ist ja erst ein Umkreis da - wie mache ich das, logisch wäre für mich, wenn das erste Element ankommt, natuerlich nichts verglichen wird.

Hier ist mal der Code des Konstruktors, in der Zeile mit dem 'erg' ist der Methodenaufruf, der den NullPointer zu Beginn ausloest. Dabei berechnet die Methode einen Radiusvergleichswert fuer U1 zu U2 und liefert entweder 1, -1 oder 0 zurück.

Danke vorab fürs Nachlegen.

Java:
// TODO Javadok
	KleinsterKreis( ArrayList<Punkt> punkte)
	{
		// Lege eine Kopie der ArrayList in den Behaelter
		punkteBehaelter = new ArrayList<Punkt>( punkte );
		System.out.println("Kleinster Kreis - Konstruktor mit Punktemenge ...");
		for ( Punkt p : punkteBehaelter )
		{
			System.out.print( p.xWert + "; " + p.yWert + " | ");
		}
		System.out.println();
		
		// Baum der die Umkreise vorhaelt
		umkreisBaum = new TreeSet<Umkreis>( new Comparator<Umkreis>(){
			@Override
			public int compare( Umkreis u1, Umkreis u2 )
			{
				// Comparator
				// Umkreise werden nach deren Radius in den Baum eingeordnet. 
				// Hier reicht der Radiusvergleichswert eines Kreises, um die Ordnung zu 
				// erstellen und der Winkelvergleichswert um zu testen, ob der Winkel 
				// des ersten kleiner als der Winkel des groesseren Kreises ist. Spaeter 
				// kann man mit der Winkelvergleichszahl auch errechnen. ob der Winkel 
				// kleiner gleich 90 Grad ist.
				// Der groesste Umkreis liegt oben im Baum und wird als uTop gegriffen.
				
				
				// Abbruch falls einer der beiden Umkreise null ist, wie etwa wenn der erste Kreis reinkommt
				/*
				if ( u1 == null || u2 == null )
				{
					// einer der Umkreise dann kannst du dir den Vergleich sparen 
					// und den Umkreis als 'ist kleiner melden'
					if ( u1 == null )
					{
						return -1; // also u2 ist groesser
					}
					
					if ( u2 == null )
					{
						return 1; // also u1 ist groesser
					}
				}
				*/
				
				//System.out.println( "KleinsterKreis - compare() - im Vergleich ");
				//System.out.println( " --> u1 mit a: " + u1.a.toString() + " b: " + u1.b.toString() + " c: " + u1.c.toString() + " wvw:" + u1.winkelVergleichsWert + "; mp: " + u1.berechneUndGibUmkreisMittelpunkt().toString() + "; radius: " + u1.berechneUndGibRadius() );
				//System.out.println( " --> u2 mit a: " + u2.a.toString() + " b: " + u2.b.toString() + " c: " + u2.c.toString() + " wvw:" + u2.winkelVergleichsWert + "; mp: " + u2.berechneUndGibUmkreisMittelpunkt().toString() + "; radius: " + u2.berechneUndGibRadius() );
				//System.out.println();
				
				int erg = u1.istRadiusKleinerAlsVergleichsUmkreis(u2);
				
				if ( erg == 1 )
				{
					// u1 groesser als u2
					//System.out.println(" --> Kreis U1 groesser als U2.");
					return 1; 
				}
				
				if ( erg == -1 )
				{
					// u1 kleiner als u2
					//System.out.println(" --> Kreis U1 kleiner als U2.");
					return -1;
				}
				
				if ( erg == 0 )
				{
					// u1 gleich u2
					//System.out.println(" --> Kreis U1 gleich U2, weiter testen mit winkelVergleichsWert ...");
					
					// teste auf winkelVergleichsWert
					long diff = u1.winkelVergleichsWert - u2.winkelVergleichsWert;
					if ( diff < 0 )
					{
						// u1-winkelVergleichsWert ist kleiner als der von u2
						// melde kleiner
						//System.out.println( " -----> winkelVergleichsWertvergleich U1 kleiner als U2.");
						return -1;
					}
					
					if ( diff > 0 )
					{
						//System.out.println( " -----> winkelVergleichsWertvergleich U1 groesser als U2.");
						return 1;
					}
					
					if ( diff == 0 )
					{
						// TODO durchdenken, ob hier ein Epsilon passend waere
						//System.out.println( " -----> winkelVergleichsWertvergleich U1 gleich U2.");
						return 0;
					}
				}
				// TODO da muss ich eine Warnung einbauen, dass ich merke wenn hier 2 zurueckkommt
				System.out.println("ACHTUNG - hier sollte ich beim Umkreisvergleich nie hinkommen.");
				return 2;
			}
		});
	}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben