jonas.kvarnstrom@liu.se 2016 Tecken och strängar i Java
Begrepp: Tecken, kodpunkter, kodningar, Unicode: A till Z och mer
Tecken Steg 1: Ett tecken (en symbol) Odelbar symbol Minsta enheten för information A B C D # "! ( ) å ä ö ċ õ ĕ ķ Ħ Ŗ ǽ Ґ ы Ω Ą Ж ΐ ਈ ਉ ਊ ਏ ਓ ਔ ਕ ਖ ਗ ਘ ਛ R M ریال 略 X 3
Teckenrepertoar 4 Steg 2: En teckenreportoar (character repertoire) Välj ut en bestämd (men inte ordnad) mängd av tillgängliga tecken w 0 M a p N! o. D b ] y 8 C L z 5 h G ( V [ c v P \ U : 7 m ; < 4 S = 2 I J _ A 1 % g F ~ R H + e & d B n s # f { k l * @ / i O ` W r > X ) 6 Q x 9 u t - K 3, T j q E? $ Y ^ Z
5 Steg 3: En kodad teckenuppsättning (coded character set, CCS) Varje tecken motsvaras av ett heltal exempel: ASCII från 0 till 127 Kodad teckenuppsättning
Kodad teckenuppsättning (2) 6 Annat exempel: ISO Latin-x ISO Latin-1: Adderar 32 kontrolltecken, 96 symboler (västeuropa) ISO Latin-2: Adderar 32 kontrolltecken, 96 symboler (östra/centraleuropa)
Kodad teckenuppsättning (3) 7 EBCDIC (IBM-stordatorer): 129 = a, 130 = b,, 137 = i, 145 = j,
Kodad teckenuppsättning (4) 8 Java 8 använder Unicode 6.2.0 https://vimeo.com/48858289 1,114,112 kodpunkter, 0 hex till 10FFFF hex >109,242 grafiska (synliga) tecken! 0000..00FF Som i ISO Latin-1 03D0..03D6 05B0..05B9 GREEK BETA SYMBOL..GREEK PI SYMBOL HEBREW POINT SHEVA..HEBREW POINT HOLAM 0A01 GURMUKHI SIGN ADAK BINDI ਈਉਊਏਓਔਕਖਗਘਛ 0EDC..0EDD LAO HO NO..LAO HO MO ໜໝༀ 2302..237A 2623 2E80..2E99 33E0 1039F 100000.. 10FFFD HOUSE..APL FUNCT. SYMBOL ALPHA BIOHAZARD CJK RADICAL REPEAT..CJK RADICAL RAP IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE UGARITIC WORD DIVIDER <private-use-100000>..<private-use-10fffd>
Teckenkodning Steg 4: Character encoding form + character encoding scheme Ungefär: Hur representerar man dessa tal som bytes i en dator? 9 ISO Latin-1: Värden 0-255 Får plats i en enda byte Trivialt
Teckenkodning (2) Unicode: >100000 tecken Räcker inte ens med 2 bytes (16 bitar) 10 Enkel representation: UTF-32 Tecken 32-bitars heltal Oftast ineffektivt Exempel: Räksmörgås 00 00 00 52 00 00 00 E4 00 00 00 6B 00 00 00 73 00 00 00 6D 00 00 00 F6 00 00 00 72 00 00 00 67 00 00 00 E5 00 00 00 73
Teckenkodning (3) 11 UTF-8: Varierande antal bytes per tecken! Räksmörgås 72 c3 a4 6b 73 6d c3 b6 72 67 c3 a5 73 (hexadecimalt) 13 bytes Ganska effektivt för engelska och liknande språk I ISO Latin-1 skulle dessa 13 bytes betyda "rã ksmã rgã s" Kodningsschema: Teckennummer Lagring som bytes 00000-0007F 00080-007FF 00800-0FFFF 10000 FFFFF 0xxxxxxx (samma som ASCII!) 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx Informativt bitmönster!
Tecken och strängar Java skiljer på: 13 Tecken Exakt en symbol Inom apostrofer: x Primitiv datatyp, char Strängar Noll eller flera symboler Inom citat: "Hello World" Objekttyp, java.lang.string
Tecken i Java Datatypen char: 16 bitar, Unicode-tecken 0 65535 char c = 'x'; char c = 120; // c=='x', eftersom Unicodetecken #120 är ett 'x'. 14 Escapekoder för "oskrivbara tecken" '\nnn': '\unnnn': Tecken med oktalt värde nnn ('\012' == tecken 10 = line feed) Tecken med hex-värde nnnn ('\u03d0' == grekiskt beta) '\b': Backspace (ASCII 8) '\t': Tab (ASCII 9) '\n': Newline (ASCII 10) '\f': Form feed (ASCII 12) '\r': Carriage return (ASCII 13) '\'': Apostrof '\\': Backslash
String 1: Strängar är objekt Strängar i Java är objekt String str = "Hello"; 16 str Object header: len chars (data) 5 Object header: length (data) ( 5) [0] H [1] e String-pekare String-objekt Teckenarray används internt för lagring Använder UTF-16 för att stödja hela Unicode: Oftast 1 char per tecken 2 chars för de "ovanligaste"
String 2: Literaler Även strängliteraler representerar objekt Kan användas "direkt" System.out.println("Hello".length()); // 5 17 Resulterar i ett String-objekt med 5 tecken Gör inte onödiga kopior new String("Hello")
String 3: Jämförelser Har två strängar samma innehåll? equals(string other), equalsignorecase(string other) 18 if (str == hello ) { // Jämför om det är samma strängobjekt == jämför pekare! if (str.equals( hello )) { // Jämför om strängarna innehåller samma tecken >>> x = "a" >>> "aa" is x * 2 False >>> "aa" == x * 2 True compareto(string other), comparetoignorecase(string other) -1 om this ska vara före other, 0 om lika, 1 om this ska vara efter other Jämför enligt Unicode-ordning: ڥ ABCD XYZ[\]^ ¾ ÀÁÂÃÄÅÆÇÈ ÔÕÖ ØÙ ĀĄ ƦƧ Ж Se även: java.text.collator Sortering enligt specifika språk (svenska: XYZÅÄÖ)
Formattering 1: Primitiva datatyper Konvertera primitiva datatyper till text: Använd de överlagrade String.valueOf()-metoderna static String valueof(char c) { static String valueof(int i) { static String valueof(boolean b) { 20 String str = String.valueOf(127); // "127"
Formattering 2: Object String Varje objekt har en strängrepresentation Metoden tostring() ärvs från Object Ska returnera en String som representerar objektet på något sätt 21 Exempel: public class Circle { private double x, y, r; private Circle(double x, double y, double r) { this.x = x; this.y = y; this.r = r; public static void main(string[] args) { System.out.println(new Circle(2.0, 4.0, 5.0)); >> java Circle Circle@a5e17120 Metoden println(object o) anropar o.tostring() Circle har ingen egen tostring() den ärvda implementationen från Object anropas klassnamn + "@" + ett unikt ID
Formattering 3: Object String Implementera en egen tostring()! 22 public class Circle { public String tostring() { return "Circle[" + x + ", " + y + ", " + r + ']'; Här adderas strängar men ett String-objekt är immutable (oföränderligt)! >> java Circle Circle[2.0, 4.0, 5.0]
Formattering 4: Strängkonkatenering StringBuilder: Manipulering av teckensekvenser Används av kompilatorn för att implementera "+" public String tostring() { return "Circle[" + x + ", " + y + ", " + r + ']'; public String tostring() { final StringBuilder buf = new StringBuilder(""); buf.append("circle["); buf.append(x); buf.append(", "); buf.append(y); buf.append(", "); buf.append(r); buf.append(']'); return buf.tostring(); StringBuilder.append(int) anropar String.valueOf() Skapa en String med samma tecken som denna StringBuilder 23
Formattering 5: Strängkonkatenering 24 Kan bli ineffektivt public class ArrayList { private Object[] elements; Vi kan ju inte private int size; ändra en //... sträng så vad public String tostring() { händer här? String res = "ArrayList<"; for (int i = 0; i < size; i++) { if (i!= 0) res = res + ", "; res = res + elements[i].tostring(); res = res + ">"; return res; Kopiera alla tecken till StringBuilder Lägg till några tecken Kopiera till en ny String Sätt om res-pekaren Släng StringBuilder + gammal String public class ArrayList { private Object[] elements; private int size; //... public String tostring() { String res = "ArrayList<"; for (int i = 0; i < size; i++) { if (i!= 0) { StringBuilder buf = new (); buf.append(res); buf.append(", "); res = buf.tostring(); StringBuilder buf2 = new (); buf2.append(res); buf2.append(elements[i].tostring()); res = buf2.tostring();
Formattering 6: Strängkonkatenering Lösning: Använd StringBuilder själv! public class ArrayList { private Object[] elements; private int size; public String tostring() { String res = "ArrayList<"; for (int i = 0; i < size; i++) { if (i!= 0) res = res + ", "; res = res + elements[i].tostring(); res = res + ">"; return res; public class ArrayList { private Object[] elements; private int size; public String tostring() { StringBuilder buf = new (); buf.append("arraylist<"); for (int i = 0; i < size; i++) { if (i!= 0) buf.append(", "); buf.append(elements[i]); buf.append(">"); return buf.tostring(); 25
Formattering 7: Detaljerad kontroll För mer detaljerad kontroll: String.format() Liknar printf() i C/C++ s=sträng d=heltal String s1 = String.format("Hello, %s! You are %d years old.\n", person.name, person.age); // Minst 30, högst 40 tecken (utfyllt med mellanslag) String s2 = String.format("Hello, %30.40s!\n", person.name); // Ange en locale String s3 = String.format(Locale.FRANCE, "e = %+10.4f", Math.E); // "e = +2,7183" 26 I PrintStream finns både println() och printf() System.out.printf("Hello, %s!\n", person.name); // Och så vidare
Formattering 8: Detaljerad kontroll 27 http://docs.oracle.com/javase/7/docs/api/java/text/messageformat.html Python >>> 'Use the {, {!'.format('power','amy') 'Use the power, Amy!' >>> "A {0 {1 is a {1 that's {0.".format('hot','dog') "A hot dog is a dog that's hot." Java String s1 = MessageFormat.format("Use the {0, {1", "power", "Amy"); String s2 = String.format("Use the %s, %s!", "power", "Amy"); String s3 = MessageFormat.format("A {0 {1 is a {1 that's {0.", "hot", "dog"); String s4 = String.format("A %0$s %1$s is a %1$s that's %0$s.", "hot", "dog");