FB18.de - Das Informatikforum
Java: char-Vergleich - Druckversion

+- FB18.de - Das Informatikforum ( /mybb )
+-- Forum: Off-Topic ( /forumdisplay.php?fid=115 )
+--- Forum: Hard- und Softwarefragen ( /forumdisplay.php?fid=48 )
+--- Thema: Java: char-Vergleich ( /showthread.php?tid=9785 )


Java: char-Vergleich - MB - 01.07.2008 11:40

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:
Code:
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 - Popcorn - 01.07.2008 12:00

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 - jo - 01.07.2008 12:02

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 - MB - 01.07.2008 12:31

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.
Code:
System.out.println("Guuuude Laune!");




RE: Java: char-Vergleich - Slater - 01.07.2008 13:28

ansonsten übrigens kürzer:
Code:
private compareChars(char c, Ding ding){
return ding.getChar() == c;
}




RE: Java: char-Vergleich - Fred - 01.07.2008 13:42

@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 - slazZ - 01.07.2008 17:55

Das geht doch so :p

Code:
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 - jo - 01.07.2008 18:14

Fred schrieb:
@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 - Slater - 01.07.2008 18:23

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 - Fred - 01.07.2008 18:57

jo schrieb:
Fred schrieb:
@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:

Code:
Character a = 'a';
char b = 'b';
boolean x = (a == b);

Und der zugehörige Bytecode:

Code:
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 - Popcorn - 01.07.2008 19:05

So, jetzt wird es schon wieder ein wenig... Ich muss hier weg. %)


RE: Java: char-Vergleich - Fred - 01.07.2008 19:28

Dass Java in Bytecode übersetzt wird, erinnerst Du aber schon noch ausm Grundstudium, oder? 25


RE: Java: char-Vergleich - Popcorn - 01.07.2008 19:29

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 - Fred - 01.07.2008 19:33

Der Decompiler für Essen heisst "massig Alkohol trinken"... 25


RE: Java: char-Vergleich - Popcorn - 01.07.2008 19:41

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 - jo - 01.07.2008 19:42

Fred schrieb:
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 - Fred - 01.07.2008 19:51

jo schrieb:
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 - Fred - 01.07.2008 20:03

Lustig ist auch das Verhalten des folgenden Codes:
Code:
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:

Zitat:
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 - UncleOwen - 01.07.2008 20:50

jo schrieb:
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 - jo - 01.07.2008 21:17

ahja da stehts:

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


15.21.2   Boolean Equality Operators == and !=

Zitat:
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 - Fred - 01.07.2008 21:27

jo schrieb:
5.6.2   Binary Numeric Promotion
Zitat:
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:

Code:
Character a = 'a';
Character b = 'a';
System.out.println(a == b);

Character x = 'ä';
Character y = 'ä';
System.out.println(x == y);




RE: Java: char-Vergleich - UncleOwen - 01.07.2008 22:20

jo schrieb:
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 - UncleOwen - 01.07.2008 22:22

Fred schrieb:
Code:
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 - Fred - 01.07.2008 23:31

UncleOwen schrieb:
Fred schrieb:
Code:
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 - UncleOwen - 02.07.2008 11:41

Fred schrieb:
UncleOwen schrieb:
Fred schrieb:
Code:
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.

Zitat:
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 - low_level - 02.07.2008 11:41

Fred schrieb:
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