Thinking in Java Chapter 13

Source: Internet
Author: User

From thinking in Java 4th Edition

The string object is immutable. Every method in the string class that looks to modify a string value is actually creating a completely new string object that contains the modified string content. The original string object is not moved:

Import static net.mindview.util.print.*;p Ublic class Immutable {public static String UpCase (string s) {return S.toupperca Se ();} public static void Main (string[] args) {String q = "Howdy";p rint (q);//Howdystring QQ = upcase (q);p rint (QQ);//Howdyprint (q );//Howdy}}/* output:howdyhowdyhowdy*/

When the Q is passed to the UpCase () method, a copy of the reference is actually passed. Whenever a string object is used as a parameter to a method, a reference is copied, and the object it refers to is always in a single physical location and never moved.

Immutability can lead to some efficiency problems. The "+" operator that is overloaded with a string object is a good example:

public class Concatenation {public static void main (string[] args) {String mango = "Mango"; String s = "abc" + "Mango" + "def" + 47; System.out.println (s);}} /* output:abcmangodef47*/

You can imagine this code working: A String object would most likely have a append () method that would generate a new string object to contain the string "ABC" after the connection to Mango. The object is then connected to "Def", generating another new string object, and so on.

[A lesson in software design: Unless you implement the system in code and let it move, you can't really understand what's wrong with it. ]

You can use StringBuilder in your code to generate a string:

public class Whitherstringbuilder {public String implicit (string[] fields) {String result = "", for (int i = 0; i < fields.length; ++i) Result + = Fields[i];return result; Public String Explicit (string[] fields) {StringBuilder result = new StringBuilder (), for (int i = 0; i < fields.length; + +) i) Result.append (Fields[i]); return result.tostring ();}}

1. In the implicit () method, the compiler creates a StringBuilder that is too early in the loop, which means that every time a loop is passed, a new StringBuilder object is created.

2. In the explicit () method, it generates only one StringBuilder object.

Therefore, when you write the ToString () method for a class, you can rely on the compiler to create reasonable string results for you if the string manipulation is simple. However, if you are using loops in the ToString () method, it is a good idea to create a StringBuilder object yourself to construct the final result:

Import java.util.*;p Ublic class Usingstringbuilder {public static Random rand = new random;p ublic String toString () {S Tringbuilder result = new StringBuilder ("["); for (int i = 0; I < 25; ++i) {result.append (rand.nextint); Result.append (",");} Result.delete (Result.length ()-2, Result.length ()); Result.append ("]"); return result.tostring ();} public static void Main (string[] args) {Usingstringbuilder usb = new Usingstringbuilder (); SYSTEM.OUT.PRINTLN (USB);}} /* output:[58, 55, 93, 61, 61, 29, 68, 0, 22, 7, 88, 28, 51, 89, 9, 78, 98, 61, 20, 58, 16, 40, 11, 22, 4]*/

The end result is a little bit of stitching with the append () statement. If you want to take a shortcut, such as append (A + ":" + C), the compiler will fall into the trap, creating an additional StringBuilder object for you to handle the character manipulation in parentheses.

StringBuilder offers a rich range of methods, including insert (), replace (), substring () or even reverse (). But the most common is append () and ToString (), and the Delete () method.

The unconscious recursion

Each class in Java is fundamentally inherited from object, and the standard container is no exception, so the container has the ToString () method:

Import Generics.coffee.*;import java.util.*;p ublic class Arraylistdisplay {public static void main (string[] args) { arraylist<coffee> coffees = new arraylist<coffee> (); for (Coffee c:new vcoffeegenerator ()) Coffees.add (c) ; SYSTEM.OUT.PRINTLN (coffees);}}

If you want the ToString () method to print out the memory address of the object, you might consider using the This keyword:

Import java.util.*;p Ublic class Infiniterecursion {public String toString () {return ' infiniterecursion Address: ' + this + "\ n";} public static void Main (string[] args) {list<infiniterecursion> v = new arraylist<infiniterecursion> (); int i = 0; I < 10; ++i) V.add (New Infiniterecursion ()); System.out.println (v);}}

Here, when you run

"Infiniterecursion Address" + This

, an automatic type conversion occurs. Converted by the Infiniterecursion type to a string type. Because the compiler sees a string object followed by a "+", and then the object is not a string, the compiler tries to convert this to the readymade moth string. The conversion is really done by invoking the ToString () method on this, so a recursive call occurs.

If you really want to print the memory address of the object, you should call the Object.ToString () method, which is the method responsible for this task. So you should not use this, but should call the Super.tostring () method.

Action on string

When you need to change the contents of a string, the method of the string class returns a new string object. At the same time, if the content does not change, the method of string simply returns a reference to the original object.

Formatted output [System.out.format ()]

The format () method introduced by Java SE5 can be used with PrintStream or PrintWriter objects, which also include System.out objects. The format () method mimics printf () from C. If you're more nostalgic, you can also use printf ():

public class Simpleformat {public static void main (string[] args) {int x = 5;double y = 5.332542;//the old way:System.out. println ("Row 1: [" + x + "+ y +"] ");//The New Way:System.out.format (" Row 1: [%d%f]\n ", x, y);/or System.out.print F ("Row 1: [%d%f]\n", x, y);}} /* Output:row 1: [5, 5.332542]row 1: [5, 5.332542]row 1: [5, 5.332542]*/

In Java, all new formatting features are handled by the Java.util.Formatter class. Formatter can be thought of as a translator that translates your formatted string and data into the desired result:

Import Java.io.*;import java.util.*;p ublic class Turtle {private string name;private Formatter f;public Turtle (String nam E, Formatter f) {this.name = NAME;THIS.F = f;} public void Move (int x, int. y) {F.format ("%s The Turtle is at (%d,%d) \ n", name, X, y);} public static void Main (string[] args) {PrintStream outalias = System.out; Turtle tommy = new Turtle ("Tommy", New Formatter (System.out)); Turtle Terry = new Turtle ("Terry", New Formatter (Outalias)); Tommy.move (0, 0); Terry.move (4, 8); Tommy.move (3, 4); Terry.move (2, 5); Tommy.move (3, 3); Terry.move (3, 3);}} /* Output:tommy the Turtle is at (0, 0) Terry the Turtle was at (4, 8) Tommy the Turtle was at (3, 4) Terry the Turtle was at (2 , 5) Tommy the Turtle is at (3, 3) Terry the Turtle are at (3, 3) */

Format specifier

The following are the abstract uses:

%[argument_index$][flags][width][.precision]conversion

1. Width: Specifies the minimum size for a field. The formatter object ensures that a domain reaches at least a certain length by filling zero when necessary. The default right alignment, "-" can change the alignment direction.

2. Precision: For string objects, specify the maximum number of characters, and for floating-point numbers, the number of digits to display for the fractional portion (default is 6-bit). cannot be applied to an integer, triggering an exception

Use the format modifier below to print a shopping receipt:

Import java.util.*;p Ublic class Receipt {private Double total = 0;private Formatter f = new Formatter (system.out);p Ublic V OID PrintTitle () {F.format ("%-15s%5s%10s\n", "Item", "Qty", "price"), F.format ("%-15s%5s%10s\n", "----", "---", "-----" );} public void print (String name, Int. qty, double price) {F.format ("%-15.15s%5d%10.2f\n", Name, qty, price); public void Printtotal () {F.format ("%-15s%5s%10.2f\n", "tax", "", total * 0.06); F.format ("%-15s%5s%10s \ n", "", "", "- ----"); F.format ("%-15s%5s%10.2f\n "," Total "," ", total * 1.06);} public static void Main (string[] args) {Receipt Receipt = new Receipt (); Receipt.printtitle () receipt.print ("Jack ' s Magic Beans ", 4, 4.25); Receipt.print (" Princess Peas ", 3, 5.1); Receipt.print (" Three Bears porridge ", 1, 14.29); Receipt.printtotal ();}}       /* Output:item Qty price------------Jack's Magic be 4 4.25Princess peas                      3 5.10Three Bears Por 1 14.29Tax   1.42-----Total 25.06*/ 

The conversion result of format conversion B is true or false. But as long as its argument is not NULL, the result is true, even if the number is 0, and the result is true. In other languages such as C, the conversion of the number 0 to false requires attention.

String.Format ()

Java SE5 also referenced the sprintf () method in C to generate a formatted string object. String.Format () is a static method that accepts the same arguments as the Formatter.format () method, but returns a string object. String.Format () is handy when you use the format () method only once:

public class Databaseexception extends Exception {public databaseexception (int transactionid, int queryid, String message {Super (Stirng.format ("(t%d, q%d)%s", TransactionID, Queryid, Message));} public static void Main (string[] args) {try {throw new Databaseexception (3, 7, "Write failed"),} catch (Exception e) {System . OUT.PRINTLN (e);}} /* Output:databaseexception: (T2, Q7) Write failed*/

A hex-dump tool

The following gadget uses the String.Format () method to print a byte array in a readable hexadecimal format:

Package Net.mindview.util;import java.io.*;p ublic class Hex {public static String format (byte[] data) {StringBuilder ResU lt = new StringBuilder (), int n = 0;for (byte b:data) {if (0 = = N) result.append (String.Format ("%05x:", N)); Result.app End (String.Format ("%02x", b)), ++n;if (0 = = N) result.append ("\ n");} Result.append ("\ n"); return result.tostring ();} public static void Main (string[] args) {if (0 = = args.length)//Test by Display this class FILE:SYSTEM.OUT.PRINTLN (format (Bi Naryfile.read ("Hex.class")), ELSESYSTEM.OUT.PRINTLN (Format (Binaryfile.read (new File (args[0))));}}

Regular expressions

In general, regular expressions describe strings in some way, so you can say, "If a string contains these things, then it's what I'm looking for."

Java has special handling for backslashes. \d represents a single digit in a regular expression. In other languages, \ \ means "I want to insert a normal (literal) backslash in the regular expression, so please do not give it any special meaning." In Java, \ \ means "I want to insert a backslash in a regular expression, so the character behind it has a special meaning." For example, if you want to represent a single number in Java, then its regular expression should be \\d. If you want to insert a normal backslash, it should be \\\. But things like line breaks and tabs only need to use the SLR slash: \n\t.

1. Indicates that there may be, should use "?"

2. Represents one or more previous expressions, you should use "+"

So to say "there may be a minus, followed by one or more digits", you can:

-?\\d+

The simplest way to apply regular expressions is to take advantage of the built-in functionality of the String class. For example, you can check whether a string matches the regular expression as described above:

public class Integermatch {public static void main (string[] args) {System.out.println (" -1234". Matches ("-?\\d+")); System.out.println ("5678". Matches ("-?\\d+")); System.out.println ("+911". Matches ("-?\\d+")); System.out.println ("+911". Matches ("(-|\\+) \\d+"));}} /* output:truetruefalsetrue*/

The string class also comes with a very useful regular expression tool, the--split () method, whose function is "to cut a string from a regular expression match":

Import java.util.*;p Ublic class Splitting {public static String Knights = "Then, if you had found the shrubbery, you mu St "+" cut down the mightiest tree in the forest ... "+" with ... a herring! "; public static void Split (String regex) {System.out.println (arrays.tostring (Knights.split (regex)));} public static void Main (string[] args) {split ("");//doesn ' t has to contain regex charssplit ("\\w+");//Non-word Characte Rssplit ("n\\w+");//' n ' followed by Non-word characters}}/* Output:[then, when, you, has, found, the, shrubbery,, you, Mustcut, down, the, mightiest, tree, in, the, forest, ... with, ..., A, herring!] [Then, when, you, has, found, the, shrubbery, you, mustcut, down, the, mightiest, tree, in, the, forest, with, a, herring ][the, whe, you had found the shrubbery, you mustcut Dow, the mightiest tree I, the forest ... with ... a herring!] */

\w represents a non-word character (if the W lowercase, \w, represents a word character). As you can see, in the original string, the part that matches the regular expression does not exist in the final result.

String.Split () also has an overloaded version that can limit the number of string splits.

The last regular expression tool that comes with the string class is replace. You can replace only the first matched substring of the regular expression, or replace all matching places:

Import static net.mindview.util.print.*;p Ublic class Replacing {static String s = splitting.knights;public static void Mai N (string[] args) {print (S.replacefirst ("f\\w+", "located"));p rint (S.replaceall ("shrubbery|tree|herring", "banana") );}}

Each of the following regular expressions can successfully match the character sequence "Rudolph":

public class Rudolph {public static void main (string[] args) {for (String pattern:new string[]{"Rudolph", "[Rr]udolph", "[ Rr][aeiou][a-z]ol.* "," r.* "}) System.out.println (" Rudolph ". Matches (pattern));}} /* output:truetruetruetrue*/

Pattern and Matcher

Rather than a finite string class, we prefer to construct powerful regular expression objects. Simply import the Java.util.regex package and use the static Pattern.compile () method to compile your regular expression. [on Unix/linux, the regular expression in the command line must be enclosed in quotation marks.] ]

Import java.util.regex.*;import static net.mindview.util.print.*;p Ublic class Testregularexpression {public static void Main (string[] args) {if (Args.length < 2) {print ("Usage: \njava testregularexpression" + "Charactersequence Regula Rexpression+ "); System.exit (0);} Print ("Input: \" + args[0] + "\" "); for (String Arg:args) {print (" Regular expression: \ "" + arg + "\"); Pattern p = pattern.compile (ARG); Matcher m = P.matcher (Args[0]), while (M.find ()) {print ("Match \" "+ m.group () +" \ "at positions" + m.start () + "-" + (M.en D ()-1));}}}

By calling the Pattern.matcher () method and passing in a string argument, we get a Matcher object. Using the methods on the Matcher object, we will be able to determine whether the various types of matches are successful:

Boolean matches () Boolean Lookingat () Boolean find () Boolean find (int start)

where the matches () method is used to determine whether the entire input string matches the regular expression pattern, and Lookingat () is used to determine whether the starting part of the string matches the pattern.

The Matcher.find () method can be used to find multiple matches in charsequence:

Import java.util.regex.*;import static net.mindview.util.print.*;p Ublic class Finding {public static void main (string[] args) {Matcher m = pattern.compile ("\\w+"). Matcher ("Evening is full of the Linnet's Wings"); while (M.find ()) PRINTNB ( M.group () + "");p rint (); int i = 0;while (M.find (i)) {PRINTNB (M.group () + ""); ++i;}} /* Output:evening is full of the Linnet s wings Evening vening ening ning ing ng g are is s full full ull ll l of of F the The He e linnet linnet innet nnet net et t s s wings Wings ings NGS GS s*/

Find () Iterates forward the input string like an iterator. The second find () can accept an integer as an argument that represents the position of the character in the string and takes it as a starting point for the search.

Thinking in Java Chapter 13

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.