cs503: second lecture, fall 2008 basic java, oop, and arrays. michael barnathan

28
CS503: Second Lecture, Fall 2008 Basic Java, OOP, and Arrays. Michael Barnathan

Post on 21-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

CS503: Second Lecture, Fall 2008Basic Java, OOP, and Arrays.

Michael Barnathan

Here’s what we’ll be learning:• Java:

– Constants (using final).– Member variables of a class.

• So far, all of the variables you worked with were local to the main() function.– Methods and constructors (similar in C++).– Static variables (using static, also in C++).– “Public”, “private”, and “package” access and the concept of least

privilege (also in C++).– “Encapsulation” (general OOP technique).

• Theory:– Unsorted Arrays.

• “CRUD” operations: Create/read/update/delete.• Linear searching.• Fixed vs. variable size arrays.

– “Growing”/“Doubling” strategy.

Back to the Guessing Game

• Here’s the code for the game itself:import java.util.Scanner;

class GuessingGame {public static void main(String[] args) {

final int maxnum = 100; //Highest number we're going to guess to.

//I'm thinking of a number...int number = (int) ((Math.random() * maxnum) + 1);

System.out.println("I'm thinking of a number between 1 and " + maxnum);

Scanner readnums = new Scanner(System.in);int guess = 0;while (guess != number) {

System.out.print("What do you think it is? ");guess = readnums.nextInt();

if (guess < number)System.out.println("Nope, higher!");

else if (guess > number)System.out.println("Nope, lower!");

elseSystem.out.println("You got it!");

}}

}

The other side of the game…

• You manually executed an algorithm to try and guess the number in the previous class.

• Today, we’ll try to write a program that will do it in Java. You are given the following class:

public class Guesser {public static final int MAXNUM = 100;private final int secret;

//Generate the secret number in the constructor.public Guesser() { secret = (int) (Math.random() * MAXNUM + 1); }

//Returns < if the number is less than the guess, > if greater, = if equal.//This uses the “ternary operator” – which is just a concise way to write if/else statements.public char guessNumber(int guess) { return (secret > guess) ? ‘>’ : ((secret < guess) ? ‘<’ : ‘=’); }

}

This has some new things that we need to know before writing anything.

Member variables.public class Guesser {

public static final int MAXNUM = 100;private final int secret;…

}• So far, we’ve only worked with local variables inside of main().

– Local variables belong to a block of code inside of a function. They go out of scope at the end of that block.

• These are member variables of class Guesser, which means that they belong to the class, not just a function inside of the class.– They will stay in scope as long as their Guesser object does.– Makes sense: they’re declared outside of any functions.

• They can be public, private, or protected. I’ll explain this later.

Final Variables• You declare constants using the final keyword in Java.• Both local and member variables can be final.• final variables may be set only once.

– Once they have a value assigned, it is an error to assign another value to them.• They are like const variables in C, with one important difference:

– They do not need to be declared and initialized in the same statement.• The following is valid in Java:

– final int secret; //Declaration.– secret = 50; //Initialization.

• But the following is not valid in C:– const int secret;– secret = 50; //Nope, you need to set it above.

• The following is not valid in either language:– final int secret = 50; //This is fine.– secret = 51; //No; it must always be 50 now.

• Why is this an important difference?– Constructors.

Methods• A method is a function inside of a class.• All functions in Java are methods.

– You can’t define functions outside of classes, like you could in C/C++.

• Like variables, methods can be public, private, or protected. Again, we’ll speak of this later.

• You’ve already written one: main.• You’ve already invoked several:

– Scanner.nextInt()– Math.random()

• Like member variables, you use the “.” operator to call methods in Java.

Constructors• A constructor is a special method that is called when an object is created.

– They are usually used to initialize an object’s member data.• Constructors always have the same name as their class and never return

anything.– Not even void.

• They can take arguments. A constructor without arguments is called a default constructor.

• Example constructors:class Guesser {

private final int secret;

Guesser() { secret = (int) (Math.random() * MAXNUM + 1); } //Default constructor.Guesser(int s) { secret = s; }

}

• This is why you must be able to set final variables later in Java – they are often set inside of constructors.

• If you don’t specify a constructor, Java will give your class an empty one by default.– If you specify any constructor, even one with arguments, Java won’t give you a

default one anymore. You must implement it yourself if you want it.

Access: public, private, package.• Both data and methods have access levels.• 4 levels: private, package, protected, public.

• Private:• Only methods within the same class can access a private member variable or method.

• Package:• Only methods within the same package (group of classes) can access these variables.

• We’ll discuss packages a bit later.• This is the default level; i.e., what you get when you leave out a “private”, “public”, or

“protected” keyword in a declaration.• Protected:

• Only members within the same package or a class that inherits from the same class have access.

• More on inheritance next week.• Public:

• Everyone can access a public member or method.• Concept of least privilege: don’t allow any more access than you need to.• Note to C++ programmers: Java doesn’t have “friend” classes.

Encapsulation

• Classes should stand on their own as much as possible.

• They do this by hiding details of their implementation (using private) and providing access to the class through public methods.– This restricts the actions the caller can take on

objects of your class to the methods you provide.– This is a good thing because you gain more control

over how your code is called.

Static Members• Both variables and methods can be static.• Normal member variables belong to an object.

– 1 object, 1 instance of the member.– Two “Employee” objects would have different names and salaries, for

example.• Static members belong to the class itself.

– 1 instance no matter how many objects.• You can invoke static members using the name of the class, without

creating an object:– For example: Math.random() is static.– So is main!

• Because static methods are not associated with a particular object, they can only access other static members on their own.– But you can declare objects of your class and access their members.

Back to the Gamepublic class Guesser {

public static final int MAXNUM = 100;private final int secret;

//Generate the secret number in the constructor.public Guesser() { secret = (int) (Math.random() * MAXNUM + 1); }

//Returns < if the number is less than the guess, > if greater, = if equal.//This uses the “ternary operator” – which is just a concise way to write if/else statements.public char guessNumber(int guess) { return (secret > guess) ? ‘>’ : ((secret < guess) ? ‘<’ : ‘=’); }

}

This class is encapsulated. There is no way for you, the caller, to find out the secret other than to guess it.

We already know the algorithm: find the midway point, guess, change the boundaries of the acceptable answers depending on whether the guess was low or high. Can you think of some code that would do it?

Analysis

• When you used this strategy manually, it took logarithmic time. Let’s take a look at the code to see whether this is still true.

All fun and games this time…• My original plan ended here, but we kept going.• The lesson:

– The principles of Java owe an intellectual heritage to C++. Much of “progress” is successive copying with some changes. Your existing knowledge will be useful to you when learning new techniques.

• Next class: Searching, basic sorting, sorted arrays, and intro. to recursion.

• Assignment 1: Design an automatic guessing game.• Due Thursday, 9/11.• Rather than having the user guess the number, have the program try to guess it according to

the strategy we discussed.• Keep track of the number of guesses required. Run the program several times and report the

average and worst number of guesses. Does this agree with our worst-case assumption of log(n)? (The base-2 log of 100 is 6.64. There’s no such thing as .64 of a guess, so round to 7).

• Try varying the maximum number the program will choose up to. How do the average and worst number of guesses increase with the input? Do they increase logarithmically?

• Remember, in CS, logarithms are base 2. To do base 2 logs on a calculator, use log(x) / log(2).• You may use the Guesser class that I provided.• Contact me with any questions.

Arrays• Reminder: Data structures are models that make certain types of access to your

data easier.• Among the simplest of these models is the array.• Arrays are contiguous homogenously typed addressable collections of data.

– Contiguous: Element 2 immediately succeeds Element 1 in memory.– Homogenous: Every element is of the same data type.– Addressable: You can access an individual item in an array based on its index.

• RAM is actually just one very big array.– Memory addresses are indices into the array.

• Both C and Java have built-in support for arrays.– You’ve seen at least one: String[] args in main.– Arrays in C are just pointers. Java gives you much more.

• When you declare an array in Java, the object gets the size.– Example: Employee[] e = new Employee[10];

• Accessing an array is simple:– System.out.println(e[0]);– The index runs from 0 to size-1.

• The most fundamental difference between arrays in C and Java:– You can get the size: System.out.println(e.length); //Prints 10.

An Array

Data 10 21 44 -13 7 26 28 14Index 0 1 2 3 4 5 6 7

Contiguous: adjacent elements are adjacent in memory.Homogenous: all elements are “int”s.

Size: 8.

A[0] = 10A[4] = 7A[8] will throw an ArrayIndexOutOfBounds exception in Java.

Random Access• CRUD operations: Let’s start with reading.• Reading an array is easy: just use arr[index].

– This is a constant-time (O(1)) operation, no matter what the index is.

– This is possible due to the contiguous and homogenous properties of the array.

• All elements are the same type.• All elements are adjacent in memory.• All Java needs to do is offset sizeof(type) * index from the start of

the array in memory – quick lookup.– This is known as “random access”.

• Because looking up a random element always takes O(1).• And this is why RAM is called “random access memory”.

Insertion on Unsorted Arrays

• Since we don’t care about the order, we can insert at the end.– If we wanted to insert in the middle, we’d need to

shift everything after it down – O(n).

• This is simple: keep a counter of how full the array is and increment it as we go.

• Let’s call it arrcount and initialize it to 0.• We can just say: arr[arrcount++] = newelem;• Since arr[arrcount] is O(1), so is insertion.

Updating

• arr[index] = newval;• Simple, easy, also O(1) due to random access.

Deletion

• Two interpretations:– The book’s: You need to shift everything beyond

the target element down.– Mine: If the order really doesn’t matter, you can

just swap with the last element and decrement the counter you’re using to keep track of the size.

– “Shift everything down” is linear – you may have to move up to n-1 items.

– The swap method is constant-time.

Unsorted arrays seem pretty good.• Insertion at end: O(1).• Insertion in the middle: O(N).• Accessing any element: O(1).• Updating an element: O(1).• Deletion (shift): O(N).• Deletion (swap): O(1).

• Why use anything else?– Using only arrays worked pretty well in VB.– We could end the course now!

Back to reality…• There are some drawbacks, however:

– If you don’t know how large the array is, you’ll have to do one of three things (all of which trade off):

• Underestimate and tell the user he’s out of space (flexibility).• Overestimate and waste space (space).• Grow the array dynamically as it gets larger (time + complexity).

– Searching for an element in the array is linear.

• Access and Search are generally the most frequent/important actions a program will take.– Unless you’re doing a lot of writing; e.g., logging data.– These are the ones we want to optimize, then.

Growing the Array• Idea: when the array runs out of space, make it bigger.• Problem: you can’t resize arrays.• Solution: create a new, larger array and copy.• Double the current size is usually a good choice.

– The overall number of doubles you’ll need to do for n insertions is O(log n).

• The algorithm:– Create a new array of size n*2: O(1).– Copy the data to the new array: O(n).– Refer the variable to the new array: O(1).

• There is a very useful Java class that will do this for you.– Look up the Vector class in the Java API.– We’ll cover these so-called “container classes” later on.

Growing the Array

Data 10 21 44 -13Index 0 1 2 3

Data 10 21 44 -13 7 26 28 14Index 0 1 2 3 4 5 6 7

A =

B =A =

Linear Search

• What’s the problem with searching an unsorted array?

Data 10 21 44 -13 7 26 28 14Index 0 1 2 3 4 5 6 7

Worst case: Find 15.

Found it?

No.

• We have to search every element: O(n).

Linear search: The Algorithm.

• You should be able to figure this one out.• It’s very intuitive.Object[] arr;for (int i = 0; i < arr.length; i++) {

if (arr[i].equals(target))return i;

}

return -1; //“Sentinel” value; not found.

Binary Search: A Better Way

• If you know the array is sorted, it’s possible to search it in O(log n) time.

• This works using the same principle as the guessing game:– Eliminate half of the array on each try.

• There are some tradeoffs to sorting the array.– See what I mean? Tradeoffs are everywhere!

• We’ll discuss this more next week.

Fin.• This is really the end. To re-post slide #14:• The lesson:

– The principles of Java owe an intellectual heritage to C++. Much of “progress” is successive copying with some changes. Your existing knowledge will be useful to you when learning new techniques.

• Next class: Searching, basic sorting, sorted arrays, and intro. to recursion.

• Assignment 1: Design an automatic guessing game.• Due Thursday, 9/11.• Rather than having the user guess the number, have the program try to guess it according to

the strategy we discussed.• Keep track of the number of guesses required. Run the program several times and report the

average and worst number of guesses. Does this agree with our worst-case assumption of log(n)? (The base-2 log of 100 is 6.64. There’s no such thing as .64 of a guess, so round to 7).

• Try varying the maximum number the program will choose up to. How do the average and worst number of guesses increase with the input? Do they increase logarithmically?

• Remember, in CS, logarithms are base 2. To do base 2 logs on a calculator, use log(x) / log(2).• You may use the Guesser class that I provided.• Contact me with any questions.