Page: (Bot) (Prev) (Next) Class: (Outline) (Summary) (Assign) (Answer) Course: (Cover) (Content) (Glossary)
IT508 - INTERNET PROGRAMMING - CLASS 4
ANSWERS

To: (Problems) (Exercises)

PROBLEMS (Top)

  1. What is the difference between an instance of a String and an instance of a StringBuffer?

    An instance of a String is immutable. It can not be changed. An instance of a StringBuffer contains a string that can be changed.

  2. Study the following source code:
            public class FormatBuffer extends StringBuffer
            {
                ... see assignment
            }
    

    1. Describe the apparent purpose of this class and its only instance operator.

      The purpose of the FormatBuffer class is to create objects that have all of the operations of a StringBuffer plus an operation that can append an integer right justified in a specified width.

    2. This code will not compile. Why not?

      The problem is that StringBuffer is declared a final class so that it can not be extended.

      Because String and StringBuffer are heavily used, they should be as efficient as possible. Making them final allows the compiler to generate more efficient code because there is no chance that a subclass might override one of it methods.

  3. Refer to the previous problem. Outline the code for a FormatBuffer class that will compile and also work correctly.

    The best that we can do is to create a new class that uses an associated StringBuffer. The only way to get the new class to have all of the operations of StringBuffer is to also implement them in the new class. But, at least we can delegate the work to the associated buffer. This will give something like:

        public class FormatBuffer
        {
    

    private StringBuffer buffer;

    public FormatBuffer(int initSize) { buffer = new StringBuffer(initSize); }

    public void append(int inum, int width) { String snum = String.valueOf(inum); int fill = width - snum.length(); while (fill-- > 0) buffer.append(' '); buffer.append(snum); }

    //StringBuffer operations

    public FormatBuffer append(boolean boo) { buffer.append(boo); }

    public FormatBuffer append(char ch) { buffer.append(ch); }

    ...... ...... }

    Perhaps this new class should have some additional capabilities including such things as:

  4. A procedural language programmer was recently introduced to Java and object oriented programming. Study the code that he wrote for an Equation class:
        public class Equation ...
    

    1. Exactly what output will be produced when the main() method is executed?
        Equation = 3.0*X*X + 2.0*X + 1.0
        for x = 1.0, value = 6.0
        x value greater than 10.0
      

    2. Use your knowledge of exceptions to simplify the code for the Equation class. You do not need to rewite the code for the toString() method.

      The String mess, isBad(), and getMessage() all deal with handling errors. They can be eliminated if exceptions are used. The best solution is to code an EquationException class. In an exam where time is critical, we might cut corners and just use a generic Exception. Here, we will do it right. The code for the exception class is:

        public class EquationException extends Exception
        {
            public EquationException()
            {
                super();
            }
      

      public EquationException(String message) { super(message); } }

      The code for the revised equation class is:

        public class Equation
        {
        //Coefficients
            private double aCoef;
            private double bCoef;
            private double cCoef;
      

      //Constructor public Equation(double a, double b, double c) { aCoef = a; bCoef = b; cCoef = c; }

      //Methods public double evaluate(double x) throws EquationException { if (x < 0.0) throw new EquationException("x value less than 0.0"); if (x > 10.0) throw new EquationException("x value greater than 10.0"); return(aCoef * x * x + bCoef * x + cCoef); }

      public String toString() { .....

      } }

    3. Rewrite the TestEquation.main() method to conform to your revised Equation class.

      Note that in the event of an error, the orignal test program just quit using the System.exit() operation. So, it is not necessary to have multiple try blocks since only one error message can ever be printed.

          public static void main(String[] args)
          {
              double value;
          //Create equation
              Equation eq = new Equation(3.0,2.0,1.0);
              System.out.println("Equation = " + eq.toString());
          //Evaluate
              try
                {
                  value = eq.evaluate(1.0);
                  show(1.0,value);
                  value = eq.evaluate(12.0);
                  show(12.0,value);
                }
              catch (EquationException error)
                {
                  System.out.println(error.getMessage());
                }
          }
      

EXERCISES (Top)

  1. In this exercise, you must modify the PersonName class. See assignment for details of the modifications.

    The solution to this exercise is contained in the following source files:

    Two of the new methods are worth exploring. One is setMailName():

      public void setMailName(String mailName)
          throws PersonNameException
        {
      //Construct parser
          StringTokenizer parser = new StringTokenizer(mailName);
      //Examine number of parts
          int parts = parser.countTokens();
          if (parts < 2)
            throw new PersonNameException
              (this,"Mail name has too few parts");
          if (parts > 3)
            throw new PersonNameException
              (this,"Mail name has too many parts");
      //Parse name into parts
          firstName = parser.nextToken();
          if (parts == 3)
            midName = parser.nextToken();
          else
            midName = null;
          lastName = parser.nextToken();
      //Invalidate formatted names
          invalidate();
        }
    

    Note the use of an instance of the StringTokenizer class to parse the components of the mail name. This class makes it relatively easy to program the method. It also makes it easier to understand what the method is trying to accomplish.

    Also note the use of a private invalidate() method to invalidate the formatted names. Rather than duplicate the code that sets the formatted names to null, that code was "factored" out of setName(). This means that if we ever change the way we invalidate the formatted names, there will only be one place that hase to be changed.

    The other method is equals():

      public boolean equals(Object obj)
        {
        //False if different object type
            if (!(obj instanceof PersonName))
              return(false);
        //Cast to PersonName
            PersonName other = (PersonName)obj;
        //Compare names
            if (!other.firstName.equals(this.firstName))
              return(false);
            if (!other.midName.equals(this.midName))
              return(false);
            return(other.lastName.equals(this.lastName));
        }
    

    Since we need to override the method as declared in the Object class, the parameter can not be typed as a PersonName. So, the method must ensure that the object that is passed is a PersonName before it can do the compare. In practice, you might want to consider both overriding and overloading the equals method:

        public boolean equals(PersonName other)
        {
        //Compare names
            if (!other.firstName.equals(this.firstName))
              return(false);
            if (!other.midName.equals(this.midName))
              return(false);
            return(other.lastName.equals(this.lastName));
        }
    

    public boolean equals(Object obj) { //If a PersonName return equals result if (obj instanceof PersonName) return(equals((PersonName)obj))); //Not a PersonName so it can't be equal return(false); }

    If you compile the classes and execute PersonNameTest, you should get the following output:
      -- INIT TEST NAME
      
         Person: Name: last=March first=David mid=L.
           getFirstName: David
           getMidName:   L.
           getLastName:  March
           getMailName:  David L. March
           getListName:  March, David L.
      
         Person: Name: last=Doe first=John mid=null
           getFirstName: John
           getMidName:   null
           getLastName:  Doe
           getMailName:  John Doe
           getListName:  Doe, John
      
         Person: Name: last=April first=David mid=L.
           getFirstName: David
           getMidName:   L.
           getLastName:  April
           getMailName:  David L. April
           getListName:  April, David L.
      
         Person: Name: last=April first=David mid=L.
           getFirstName: David
           getMidName:   L.
           getLastName:  April
           getMailName:  David L. April
           getListName:  April, David L.
      
         Person: Name: last=Smith first=Robert mid=null
           getFirstName: Robert
           getMidName:   null
           getLastName:  Smith
           getMailName:  Robert Smith
           getListName:  Smith, Robert
      
      ** PersonName error Mail name has too many parts
           PersonName: Name: last=null first=null mid=null
      
      PersonNameException: Mail name has too many parts
      	at java.lang.Throwable.(Compiled Code)
      	at PersonName.setMailName(Compiled Code)
      	at PersonName.(Compiled Code)
      	at PersonNameTest.execute(PersonNameTest.java:40)
      	at PersonNameTest.main(PersonNameTest.java:50)
      
      -- TERM TEST NAME
      Type any char to exit ...
    


Page: (Top) (Prev) (Next) Class: (Outline) (Summary) (Assign) (Answer) Course: (Cover) (Content) (Glossary)

Prepared by David L. March -- Last Revised on September 25, 1998
COPYRIGHT © 1998 BY DAVID L. MARCH