Week 12 - Monday What did we talk about last time? Defining classes Class practice Lab 11 We can extend the idea of moving balls further Let’s make some balls hunters and some balls prey Hunters search for the nearest prey If they reach a particular prey, they eat it Prey balls always head away from the nearest hunter The Prey class has: x Location: y Location: Aliveness: Speed: double double boolean double It also has accessors for x, y, and aliveness and a method we can use to kill the prey Finally, it has an update method where it decides what it will do next The Hunter class has: x Location: y Location: Speed: double double double It also has accessors for x and y Finally, it also has an update method where it decides what it will do next Members are the data inside objects But, sometimes, wouldn’t it be nice if some data were linked to the class as a whole, rather than just the object? What if you wanted to keep track of the total number of a particular kind of object you create? Static members are stored with the class, not with the object public class Item { private static int count = 0;// one copy total private String name; // one copy per object public Item( String s ) { name = s; count++; // updates global counter } public String getName() { return name; } } public static int getItemsInUniverse() { return count; } Static members are also called class variables Static members can be accessed by either static methods or regular methods (unlike normal members which cannot be accessed by static methods) Static members can be either public or private In general, static variables should not be used Sometimes a value will not change after an object has been created: Example: A ball has a single color after it is created You can enforce the fact that the value will not change with the final keyword A member declared final can only be assigned a value once Afterwards, it will never change Using final, we can fix the value of a member It will only be set once, usually when the constructor is called It is customary to use all caps for constant names public class Animal { private String name; private final boolean MAMMAL; // never changes public Animal( String s, boolean mammal ) { name = s; MALE = mammal; } } public void evolve() { MAMMAL = !MAMMAL; } // compile-time error! It is possible to set a static member to be constant using the final keyword Usually, this is used for global constants that will never ever change Making these values public is reasonable Since they never change, we never have to worry about a user corrupting the data inside of the object The number of sides of a pentagon is always 5 Other code can access this information by using the value Pentagon.SIDES Exactly like Math.PI or Math.E public class Pentagon { private double x; private double y; public static final int SIDES = 5; // never changes public Pentagon( double newX, double newY ) { x = newX; y = newY; } public double getX() { return x; } } public double getY() { return y; } We want to compare the running time of one program to another We want a mathematical description with the following characteristics: Worst case We care mostly about how bad things could be Asymptotic We focus on the behavior as the input size gets larger and larger First, let’s compute an expression that gives us running time for a program Assume that any single line of code that doesn’t call a method or execute a loop takes 1 unit of time Then, we sum up the number of lines that are executed in a method or in a loop Add up the operations done by the following code: int sum = 0; for( int i = 0; i < n; i++ ) sum += i; System.out.println("Sum: " + sum); Initialization: 1 operation Loop: 1 initialization + n checks + n increments + n additions to sum = 3n + 1 Output: 1 operation Total: 3n + 3 We could express the time taken by the code on the previous slide as a function of n: f(n) = 3n + 3 This approach has a number of problems: We assumed that each line takes 1 time unit to accomplish, but the output line takes much longer than an integer operation This program is 4 lines long, a longer program is going to have a very messy running time function We can get nit picky: Does sum += i; take one operation or two if we count the addition and the store separately? In short, this way of getting a running time function is almost useless because: It cannot be used to give us an idea of how long the program really runs in seconds It is complex and unwieldy The most important thing about the analysis of the code that we did is learning that the growth of the function should be linear A general description of how the running time grows as the input grows would be useful Enter Big Oh notation Big Oh simplifies a complicated running time function into a simple statement about its worst case growth rate All constant coefficients are ignored All low order terms are ignored 3n + 3 is O(n) Big Oh is a statement that a particular running time is no worse than some function, with appropriate constants 147n3 + 2n2 + 5n + 12083 is O(n3) n1000 + 2n is O(2n) 15n2 + 6n + 7log n + 145 is O(n2) 659n + nlog n + 87829 is O(n log n) Note: In CS, we use log2 unless stated otherwise More on Big Oh notation Searching Sorting Keep working on Project 4 Due this Friday