FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Hard- und Softwarefragen

Java: char-Vergleich

Java: char-Vergleich 2008-07-01 11:40
MB
ich stehe gerade auf dem schlauch und frage mich, ob meine geistigen fähigkeiten nun endgültig abhanden gekommen sind oder ich in in SE1/2 gar nichts gelernt habe:

ich möchte zwei chars vergleichen, in etwa so:
private compareChars(char c, Ding ding){ if(ding.getChar() == c) { return true; } else { return false; }}
warum liefert diese Methode im Falle von c='+' nie true, wenn auch ding.getChar() == '+'? bei gewöhnlichen lettern funktioniert es. checke ich nicht.
danke für hilfe

RE: Java: char-Vergleich 2008-07-01 12:00
Popcorn
Da wird sicherlich gleich fähigere Hilfe kommen, ich bin aus Java wirklich schon lange raus. Aber ich glaube, mit == guckst Du nur, ob das die gleichen Objekte sind. Da muss irgendeine isEquivalent-Funktion benutzt werden. Meine Vermutung, vielleicht macht da ja gerade etwas Klick bei Dir.

RE: Java: char-Vergleich 2008-07-01 12:02
jo
vielleicht gibt getChar nen Character Objekt zurück?

dann müsstest du noch mit charValue() den char da rausholen (oder equals benutzen?)

RE: Java: char-Vergleich 2008-07-01 12:31
MB
habe die lösung bzw. den fehler gefunden und dieser war so oft an ganz anderer stelle versteckt, als ich dachte. daher merke ich mir fortan:
mit einem "break" sollte man sparsam umgehen, vorallem wenn es an falscher stelle steht und dann jeden aufruf dieser methode immer sofort beendet.

geil, danach habe ich den ganzen vormittag gesucht.
System.out.println("Guuuude Laune!");

RE: Java: char-Vergleich 2008-07-01 13:28
Slater
ansonsten übrigens kürzer:
private compareChars(char c, Ding ding){ return ding.getChar() == c; }

RE: Java: char-Vergleich 2008-07-01 13:42
Fred
@Popcorn: char ist ein primitiver Datentyp, da kann man ruhigen Gewissens mit == vergleichen.

@jo: Das macht Autoboxing automatisch, char kannst Du direkt mit Character vergleichen.

@Slater: Danke, genau den "Trick" predige ich auch immer [25]

RE: Java: char-Vergleich 2008-07-01 17:55
slazZ
Das geht doch so :p

private compareChars(char c, Ding ding) { boolean result = false; char tmpchar = ding.getChar(); if(tmpchar == c) {    result = true; } else {    result = false; } return result; }

RE: Java: char-Vergleich 2008-07-01 18:14
jo
@jo: Das macht Autoboxing automatisch, char kannst Du direkt mit Character vergleichen.

Wird in so einem Fall das Wrapper Object also automatisch ausgepackt? Könnte ja auch andersrum gehen und der char in ein Character gepackt werden.

RE: Java: char-Vergleich 2008-07-01 18:23
Slater
tja, da kann man nur auf Java vertrauen,
ein Charakter-Objekt zu erstellen wäre schon sehr übel,
falls nicht aus einem Cache, dann automatisch ein false beim Vergleich,
andersrum ist es viel leichter

Problem und Beweis zugleich:
   Character a = null;
   System.out.println(a == 'a');

-> NullPointerException


           edit: ist diese Einrückung durch einfache Leerzeichen neu? nun noch Monospaced-Font, wer braucht da dann noch Code-Blocks? ;)

RE: Java: char-Vergleich 2008-07-01 18:57
Fred
@jo: Das macht Autoboxing automatisch, char kannst Du direkt mit Character vergleichen.
Wird in so einem Fall das Wrapper Object also automatisch ausgepackt?
Meine Intuition sagt: ja. Da Dich das aber sicher nicht zufriedenstellt, hier ein Ausschnitt eines Testprogramms:
Character a = 'a'; char b = 'b'; boolean x = (a == b); Und der zugehörige Bytecode:
0: bipush 97 2: invokestatic #16; //Method java/lang/Character.valueOf:(C)Ljava/lang/Character; 5: astore_1 6: bipush 98 8: istore_2 9: aload_1 10: invokevirtual #22; //Method java/lang/Character.charValue:()C 13: iload_2 14: if_icmpne 21 17: iconst_1 18: goto 22 21: iconst_0 22: istore_3 Der Befehl ab Offset 10 sorgt für das automatische Unboxing, und der Vergleich ab Offset 14 basiert auf Integer-Werten.

RE: Java: char-Vergleich 2008-07-01 19:05
Popcorn
So, jetzt wird es schon wieder ein wenig… Ich muss hier weg. %)

RE: Java: char-Vergleich 2008-07-01 19:28
Fred
Dass Java in Bytecode übersetzt wird, erinnerst Du aber schon noch ausm Grundstudium, oder? [25]

RE: Java: char-Vergleich 2008-07-01 19:29
Popcorn
Selbstredend. Aber auch wenn ich weiß, dass mein Essen im Magen verdaut wird, komme ich trotzdem nicht auf die Idee, es mir da anzugucken. [24]

RE: Java: char-Vergleich 2008-07-01 19:33
Fred
Der Decompiler für Essen heisst "massig Alkohol trinken"… [25]

RE: Java: char-Vergleich 2008-07-01 19:41
Popcorn
Bevor der fertig ist, gibt es bei mir seid Jahren immer eine Magenkrampf-Exception. Das hat aber auch wesentliche Vorteile. Und wie gesagt, ich habs ja nicht so mit dem Decompilieren. %) Obwohl… Pilsstrip habe ich mal decompiliert, weil ich die Blondine endlich mal in Natura sehen wollte. [22]

RE: Java: char-Vergleich 2008-07-01 19:42
jo
Meine Intuition sagt: ja. Da Dich das aber sicher nicht zufriedenstellt, hier ein Ausschnitt eines Testprogramms:

Ja Stimmt :D Danke fürs Testprogramm.

Am zufriedensten wär ich aber mit der entsprechenden Regel aus den Java Docs. Ich kann da allerdings nichts zu bei Google finden. Ist das überhaupt spezifiziert?

RE: Java: char-Vergleich 2008-07-01 19:51
Fred
Am zufriedensten wär ich aber mit der entsprechenden Regel aus den Java Docs. Ich kann da allerdings nichts zu bei Google finden. Ist das überhaupt spezifiziert?
Ich kann da auf die Schnelle auch nichts finden, schon komisch. Falls ich noch was finden sollte, melde ich mich wieder.

RE: Java: char-Vergleich 2008-07-01 20:03
Fred
Lustig ist auch das Verhalten des folgenden Codes:
public class Boxing {     private static void test(Character a, Character b)     {         System.out.println("boxing");     }          private static void test(char a, char b)     {         System.out.println("unboxing");     }          public static void main(String[] args)     {         Character a = 'a';         char b = 'b';         test(a, b);     } } Ich hatte ja erwartet, dass der Compiler sich für eine Variante entscheidet, aber stattdessen gibt's ne Fehlermeldung:
reference to test is ambiguous, both
method test(java.lang.Character,java.lang.Character) in Boxing and
method test(char,char) in Boxing match test(a, b);
Lustigerweise beschwert sich Eclipse aber nur bei der zweiten test-Methode darüber, dass die Methode niemals aufgerufen wird. Wenn ich den test(a, b); Aufruf entferne, werden beide Methoden gelb markiert… jemand Lust auf nen Bug-Report?

RE: Java: char-Vergleich 2008-07-01 20:50
UncleOwen
Am zufriedensten wär ich aber mit der entsprechenden Regel aus den Java Docs. Ich kann da allerdings nichts zu bei Google finden. Ist das überhaupt spezifiziert?

Guckst Du hier, insbesondere 15.21.2, 5.1.8 und 5.6.2.

RE: Java: char-Vergleich 2008-07-01 21:17
jo
ahja da stehts:

5.6.2 Binary Numeric Promotion
If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed.

15.21.2 Boolean Equality Operators == and !=
If one of the operands is of type Boolean it is subjected to unboxing conversion (§5.1.8).

In 5.1.9 Unchecked Conversion konnte ich jetzt nichts dazu finden aber das oben sagt es ja schon.

RE: Java: char-Vergleich 2008-07-01 21:27
Fred
5.6.2   Binary Numeric Promotion
If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed.
Jo, beim == operator muss man da aber aufpassen, da passiert Unboxing nur, falls GENAU EIN Operator ne Referenz ist. Wenn man zwei Character-Objekte mit == vergleicht, gibt es keinen Grund fürs automatische Unboxing. Das gibt dann sehr lustige, implementationsbedingte Effekte:
Character a = 'a'; Character b = 'a'; System.out.println(a == b); Character x = 'ä'; Character y = 'ä'; System.out.println(x == y);

RE: Java: char-Vergleich 2008-07-01 22:20
UncleOwen
In 5.1.9 Unchecked Conversion konnte ich jetzt nichts dazu finden aber das oben sagt es ja schon.

Oops, *editier*.

RE: Java: char-Vergleich 2008-07-01 22:22
UncleOwen
Character x = 'ä'; Character y = 'ä'; System.out.println(x == y);

Cool, den muss ich mir merken. Falls mal jemand behauptet, in Java gaebs kein implementation defined/undefined behaviour.

RE: Java: char-Vergleich 2008-07-01 23:31
Fred
Character x = 'ä'; Character y = 'ä'; System.out.println(x == y);
Cool, den muss ich mir merken. Falls mal jemand behauptet, in Java gaebs kein implementation defined/undefined behaviour.
Der von Dir gequotete Teil liefert ja eigentlich genau das, was man erwartet.

Findest Du es nicht eher erstaunlich, dass die beiden 'a'-Objekte dieselben sind? Das liegt am internen Caching der ersten 128 Zeichen durch Character.valueOf(char c), welches beim Autoboxing verwendet wird (es wird NICHT new Character(char c) verwendet!).

Implementation defined behavior findest Du an vielen Stellen, an denen man optimieren kann. Siehe z.B. die replace-Methoden von String. Wenn es effektiv nichts zu ersetzen gibt, liefern die denselben String zurück, der reinkam. Das muss nicht so sein und war auch afair nicht immer so.

Undefined behavior kriegst Du ganz leicht, indem Du verschiedene Threads ungeschützt auf ein und dieselbe Variable zugreifen lässt.

RE: Java: char-Vergleich 2008-07-02 11:41
UncleOwen
Character x = 'ä'; Character y = 'ä'; System.out.println(x == y);
Cool, den muss ich mir merken. Falls mal jemand behauptet, in Java gaebs kein implementation defined/undefined behaviour.
Der von Dir gequotete Teil liefert ja eigentlich genau das, was man erwartet.

Findest Du es nicht eher erstaunlich, dass die beiden 'a'-Objekte dieselben sind? Das liegt am internen Caching der ersten 128 Zeichen durch Character.valueOf(char c), welches beim Autoboxing verwendet wird (es wird NICHT new Character(char c) verwendet!).

Die ersten 128 Zeichen müssen gecached werden, die restlichen dürfen. Das war das, was ich meinte.

Implementation defined behavior findest Du an vielen Stellen, an denen man optimieren kann. Siehe z.B. die replace-Methoden von String. Wenn es effektiv nichts zu ersetzen gibt, liefern die denselben String zurück, der reinkam. Das muss nicht so sein und war auch afair nicht immer so.

Undefined behavior kriegst Du ganz leicht, indem Du verschiedene Threads ungeschützt auf ein und dieselbe Variable zugreifen lässt.

Stimmt… wobei Threads da eh doof sind [24]

RE: Java: char-Vergleich 2008-07-02 11:41
low_level
Findest Du es nicht eher erstaunlich, dass die beiden 'a'-Objekte dieselben sind? Das liegt am internen Caching der ersten 128 Zeichen durch Character.valueOf(char c), welches beim Autoboxing verwendet wird (es wird NICHT new Character(char c) verwendet!).

Autsch. Ich dachte immer, ich könnte Java. Da muss ich mir wohl nochmal JLS3 durchlesen.

Roland