CS62 - Spring 2010 - Lecture 3

  • TA hours

  • Sent a test message (asgn0)

  • Problem 2.3: What are the "pre" and "post" conditions for String's concat method?

  • Extensible arrays
       - A quick recap on the java.util.Vector class
          - Vector v = new Vector();
          - What methods do we have?
             - get
             - set
             - add
             - size
       - How do you think the class is implemented implemented?
       - show VectorExamples code
          - What will basicVectorUsage() print out?
             - notice that you can change the limit in the for loop from 1000 to 10000 to 100000 and the code still works fine (but prints out a different size)
          - What happens if I run gotcha()?
          - Why does typeCastingVectors() not compile?
             - all of the operations are with respect to Objects, why?
             - we need to type cast them back to the appropriate object (don't get this wrong :)
       - run-time/cost/number of operations
          - what is the run-time of get, set and size?
             - constant
          - what about add?
             - If we have n elements in the Vector, what would be the cost of an add if we just expanded the underlying array by 1 and copied the data over?
                - n - linear
             - What about if we double the size of the array every time it fills up?
                - need to talk about the "amortized" or average cost of an add operation
                - let's average the cost of inserting all n elements
                   - cost = 1 + 2 + 4 + 8 + ... + n/4 + n/2 + n = n-1 + n = 2n - 1
                   - average = 2n-1/n ~= 2, which is still a constant amount of work per add!
       - http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html
          - a number of different constructors
             - what do you think the "capacityIncrement" variable does?
          - two add methods
             - add(Object o) to the end of the array
             - add(int index, Object element)
          - capacity() vs. size()
          - remove(int index), removes the element at the specified index and shrinks the array down
          - Why are all of the operations with respect to the Object class?
       - slightly better alternative is java.util.ArrayList; I'll talk more about why later on, but the interface is the same and we'll use this one in the class.
       - We'll talk more about efficiency of the different operations in a few weeks

  • show GenericsExamples code
          - what does the sumElements method do?
             - (note, we're using the ArrayList method from the java.util package)
          - what will happen if we run:
             - System.out.println(sumElementUser1());
             - System.out.println(sumElementUser2());
          - Why does sumElementsUser2 compile?
             - ArrayList can contain any object type
             - we don't catch this until runtime
          - In general, the earlier you can catch a bug the better
             - better to catch a bug at compile-time than run-time
             - better to catch a bug with an assert call than later on via an exception
             - better to catch a logical error with a unit/functional test than in an overall system test or user test
          - How can/should we fix this?
             - One option would be to make a new class called IntegerArrayList that ensured that only integers would be used
             - A better option is to use generics (or parameterized data types)

  • generics (or parameterized data types)
       - What is polymorphism?
          - poly, means many
          - morphism means shape or form (e.g. metamorphism, isomorphism, dimorphism)
          - In CS, polymorphism refers to things that can serve multiple functions
             - in our case, we'd like to have polymorphic typed data structures:
                - they have the same interface
                - but work on many different types of data
       - Generics allow us to define the interface to a data structure just once, but allow it to store many different data types
       - In our summing example, we'd like it to use ArrayList, but we'd like to add the restriction that it must be an ArrayList of integers
       - In addition to the type (ArrayList) we can specify what type the ArrayList stores using <>
          - ArrayList<Integer> list; // ArrayList of Integers
          - ArrayList<String> list; // ArrayList of Strings
          - ArrayList<ArrayList<Boolean>>; // An ArrayList of ArrayLists of Booleans
       - We can change both sumElementUser1 and sumElementUser2 to appropriate specify the types of the ArrayList
       - Further, compare sumElements vs sumElementsWithGenerics
          - specify in the parameters that it must be an Integer array
          - can only be called with an Integer ArrayList
          - if we try to call sumElementsWithGenerics we notice at <i>compile time</i> that it sumElementUser2 is not appropriate
          - in addition, because we know that it is an ArrayList of Integers, we no longer have to do the typecasting!
       - In this class, we will <b>always</b> use generics for a data structure when applicable (the compiler often warns you that you should be using them)

  • Look at Vector code
       - To design our own class using generics we first declare our <i>generic</i> types in the class header
          - you are declaring a type variable (that can be used in place of a type)
          - like variable names, class names, etc. you can use any name you want here
          - the convention is to user an uppercase letter (e.g. E, K, V)
          - you can declare multiple types by comma separating them within the <>
          - notice in the javadoc the @param command is used for the class documentation
       - You then use this type throughout your code as if it were any other type
          - public E get(int i)
          - public void Add(E elt)
       - The one restriction is that you cannot create a new array of your type, so we're generally use Objects, within our code
          - new E[10] is <b>NOT</b> permitted
       - We still have to do the typecasting in our Vector class. Why is this better?
          - we only need the typecast here to make the compiler happy since the only way to add elements is via the add method, which only allows elements of type E


  • How can we return multiple objects/data types from a method in java?
       - The bad way: public void Object[] method()
       - The good way: implement a Pair class using generics
          - Should be typed, i.e. contain two types
          - What methods should the class contain?
          - Constructor(s)?
          - private instance variables
       public class Pair<F, S> {
          private F first;
          private S second;
       
          public Pair(F first, S second){
             this.first = first;
             this.second = second;
          }
       
          public F getFirst(){
             return first;
          }

          public S getSecond(){
             return second;
          }
       }
       - And we could use it like:
       public Pair<Integer, String> method(){
          ...
          return new Pair<Integer, String>(4, "this is another string");
       }

  • Why do we have the classes Integer, Double, Float, Long, Boolean, etc. (8 total) when we already have built-in types?
       - built-in types are different than classes
       - when we need a representation of a built-in type that behaves as a class, we user a "wrapper" class
       - otherwise, wouldn't be able to use them with our ArrayList (or other data structures) because they don't inherit from Object

  • java.util.Scanner (http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html)
       import java.util.Scanner
       ...

       Scanner scanner = new Scanner(System.in);
       // or Scanner scanner = new Scanner(new File("the_filename"));
       
       - methods
          - int nextInt()
          - boolean hasNextInt()
          - int nextDouble()
          - int next() // next token, delimited by whitespace
          - int nextLine();

  • java.lang.StringBuffer