Chapter6

Un article de Sometimes Kitties Think Too.

SCJP


Sommaire

Chapter 6 - Strings, I/O, Formatting, and Parsing


Strings

+ strings are Objects composed of 16-bit Unicode characters

+ strings are immutable - once created the content doesn't change

+ String class is marked final

+ There exists a String constant pool from which strings are pulled


+ Different ways of creating strings:

       String s1 = "abc" 
                       --> creates 1 String object and 1 reference variable
       String s2 = new String("abc") 
                       --> creates 1 String object, 1 reference variable 
                           and 1 literal that gets placed in the string 
                           constant pool (assuming it's not already there)


        s1 != s2           
                       --> the references are different even though objects are the same
        s1.equals(s2)


Common String Methods

         charAt(), 
         concat(), 
         equalsIgnoreCase(), 
         length(), 
         replace(), 
         substring(), 
         toLowerCase(), 
         toString(), 
         toUpperCase(), 
         trim()
  + Strings have length() method, arrays have length attribute
  + "+" operator overloaded for Strings

StringsBuffer & StringBuilder

  + StringBuilder and StringBuffer should be used when making many changes 
    to a string because otherwise a lot of intermediate String objects will be abandoned
  + StringBuilder (new as of Java5) is not thread-safe, not synchronized
  + StringBuffer strings are mutable, DO NOT override equals() method
  
    therefore, (new StringBuffer("abc)).equals(new StringBuffer("abc))) ---> false

File Navigation and I/O

 + the different levels of I/O

(( File )) - representation of file and directory pathnames

(( FileReader\FileWriter )) - reads character files. Usually wrapped by BufferedReaders

(( BufferedReader\BufferedWriter )) - read large chunks of data at once and stores in buffer

(( PrintWriter )) - new methods like format(), printf() and append()

  + Stream classes read/write bytes (more about serialization than I/O) while Readers/Writers do characters

Creating Files

       + File objects used to represent the file handle, not the data
       + only createNewFile() creates the file on disk (only if already doesn't exist)
       + flush() ensures that all buffered FileWrite operations will execute before file is closed

I/O Tree

                   -------------------------------------------------------------------------------------------------
                   |                                  Object                                                       |
                   -------------------------------------------------------------------------------------------------
                                     |                                             |
                                     V                                             V
                              java.io.OutputStream                           java.io.Writer
                                /                                           /       |     \
                               /                                           /        |      \   
                              v                                           v         |       v
                java.io.FilterOutputStream                        PrintWriter       |      BufferedWriter                                                                                
                       /     |       \                                              |     
                      /      |        \                                       OutputStreamWriter
                     v       |         \                                        |         
        DataOutputStream     |          \                                       |         
                             |           V                                      |     
                             |     BufferedOutputStream                         v
                             |                                              FileWriter
                             |
                             V
                         PrintStream


I/O Classes

 +----------+-----------------------------------------------------------------------+
 |  Type    |     Constructor			   Methods   			    |
 +----------+-----------------------------------------------------------------------+
 |  Object  |     File(), File(String s)	|  mkdir(),                         |
 |          |     File(File f, String s)        |  list(), listFiles()              |
 |          |                                   |  createNewFile()                  |
 |          |                                   |  renameTo()                       |
 |	    |     	                        |  delete(),                        |
 |          |                                   |  exists(),                        |
 |          |                                   |  isFile()                         |
 +----------+-----------------------------------------------------------------------+
 |  Writer  |     FileWriter(File f)		| close(), flush(), write()	    |
 |	    |     FileWriter(String s)		| 				    |
 +----------+-----------------------------------------------------------------------+
 |  Writer  |     BufferedWriter(Writer w)	| close(), flush(), write(), 	    |
 |          |					|	newLine()		    |
 +----------+-----------------------------------------------------------------------+
 |  Writer  |     PrintWriter(Writer w)		| close(), flush(), write(), 	    |
 |          |     PrintWriter(OutputStream o)   | format(), printf(), println()	    |
 |          |     PrintWriter(String s)*	|				    |
 |          |     PrintWriter(File f)*		|				    |
 +----------+-----------------------------------------------------------------------+
+ File("something") - if "something" doesn't exist, then no file created
+ creating a directory is 2-step process 1) Create File object 2) mkdir()
+ Writer/Reader automatically create file if doesn't exist...not true with directories	
+ printf() and format() have same functionality in PrintWriter
+ renameTo(File f) takes a File object with a name
+ delete() can't delete directory if not empty

FilenameFilter

+ java.io.FilenameFilter is an interface which has one method:  boolean accept(File dir, String name)
+ can pass FilenameFilter to File's list() or listFiles()
+ list() --> String[]
+ listFiles() --> File[]

Serialization

  + ObjectOutputStream/ObjectInputStream are higher classes that wrap lower classes
   e.g.
   ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.ser") );
   os.writeObject(obj_to_be_serialized);
   
  + serializing one object takes care of the object's entire object graph 
           (as long as they implement Serializable)
  + transient - skips serialization
  + Static variables aren't serialized
  + for classes in an object's graph that aren't serializable you must use
            * private void writeObject(ObjectOutputStream os) { }
            * private void readObject(ObjectInputStream os) { }

???what about super-constructors. What about object graphs that don't implement Serializable???

  + for objects whose superclasses do NOT implement the Serializable interface the superclass MUST have a no-args constructor
  + if any superclass violates this rule then a java.io.InvalidClassException will be thrown

How to Manually Serialize Objects

  1. Declare the variable transient
  2. Write writeObject/readObject methods
  3. write/readObject throw exceptions
  4. Invoke defaultWriteObject()
  5. Do extra stuff...repeat extra stuff in same order in readObject()
  6. Invoke defaultReadObject()
  7. Do extra stuff
  8. Build new object with the serialized value


  + unserialized happens in  FIFO order
  + Object does not implement Serializable
  + any class extending Serializable objects automatically implement Serializeable
  + The order of instantiation does not happen when an object is de-serialized
   The constructor does NOT run if the class/superclass is Serializable
  
  + if a serializable object inherits from a non-serializable class, all inherited variables 
    from the superclass(es) will be de-serialized with default values because the non-serializable 
    class constructor WILL run  
  + if a collection/array is serializable, then every element therein must be serializable
  + static variables do not get serialized (because they are not part of the object (only class))
  + beware of verisoning issues with serialization
  + If you serialize a collection or an array, every element must be serializable!
  • java.io.Externalizable
     Allows an object explicit control over selialization process.  Externalizable extends Serializable interface

Dates/Numbers/Currency


How to print dates???

	Class	        |	Method
	---------------------------
	Date	        |	toString()
	Calendar        |	getTime()
 	DateFormat      |    getInstance(), format(), parse()
        NumberFormat    |  getInstance()

  • java.util.Date
       (deprecated)
       + Date class is deprecated but is still used for 1) legacy code, 2) quick 3) as a bridge between Calendar and DateFormat
       + internally a Date is stored as a long


  • java.util.Calendar
       + converts multiple dates and times
       + calendar is __abstract__, so use static method getInstance() (which standardly gives you GregorianCalendar)
       + assign Date to a Calendar class via setTime() to lock down a certain date


  • java.text.DateFormat

+ DateFormat is __abstract__, must use getInstance() or getDateInstance()

       + getDateInstance() is an overloaded method and can take nothing, DateFormat.SHORT, etc... 
 
       + parse(String s): if String is provided as an argument, can throw ParseException
       + DateFormat.format(Date d)
       + DateFormat and NumberFormat can only have their Locales set at the time of instantiation


  • java.text.NumberFormat
       + NumberFormat is __abstract__, use getInstance(Locale l), getCurrencyInstance(Locale l)
       + getPercentInstance() - returns a percent formatted number
       + Number parse(String source) 
       + String format(long number | double number) 


  • java.util.Locale - used to format for specific locations
       + setDefault sets default Locale for a class
       public static void setDefault(Locale l)

Parse, Tokenize, Format

+ In general, a regex search runs from left to right, and once a source's character has been used in a match, it cannot be reused.

     +  greedy Quantifiers:  *, +
         use *? and +? to make them reluctant quantifiers
     + \d A digit
       \s A whitespace character
       \w A word character (letters, digits, or "_" (underscore))
     + modifiers such as i,a,g, etc.... go in the front
       e.g. to match lower case:
         Pattern.compile("(?i)\\d\\d");
     + must use m.start() in conjunction with m.find()
     + java.util.Scanner() works like regex.  Returns String tokens
     + Scanner has method findInLine() which is like the Matcher.compile
     + Matcher.appendReplacement(StringBuffer, String) -- 
            appends everything up to next match and the replacement value (to the StringBuffer)
     + Matcher.appendTail(StringBuffer)  -- 
            appends charcters from given input seq

Tokenize

  String.split(expr1, limit)  
  
  + returns an array of tokens
  + expr1 is a regex
  + remember, escape the regex.  * needs to be written as "\\*"

Formatting

  + use System.out.printf("%d", i);
    %d -- integers
    %s -- strings
    %S -- capitalized strings
    %c -- char value
    %b -- boolean 
    %f -- float
    #$ -- reorders arguments according to specified integer
    %3.4f ---> print 3 places to right of float and 4 places to left of float
    format("first %2$s and first %1$b", b,s);