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