You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every method in interface must be public (public by default)
Variables will be public static final, no instance variables for interfaces
Abstract Classes
abstract keyword for abstract methods
Can provide any kind of variables & methods
Subclasses can only extend one (abstract) class
Autoboxing
Arrays never autoboxed/unboxed (e.g. Integer[] cannot be used in place of int[] & vice versa)
Can cast int to Integer
Promotion/Primitive Widening
Similar thing happens when moving from primitive type w/ narrower range to wider range
Value is promoted
double wider than int → can pass int as arg to method that declares double param
To move from wider format to narrower format, must use casting
Immutability
final helps compiler ensure immutability, not guarantee
Neither necessary nor sufficient for immutability
Can assign value only once (in constructor of class or initializer)
Declaring reference final does not make object referred to by reference immutable
public final ArrayDeque<String> d = new ArrayDeque<>();
Memory box d not allowed to point at any other ArrayDeque, can't be changed to point at different ArrayDeque
Referenced ArrayDeque itself can change
Generic Methods
Types inferred from type of object passed in
Type Upper Bounds
Can use extends keyword as type upper bound
Used as statement of fact, doesn't change definition/behavior of generic method parameter
Checked vs Unchecked Exceptions
Any subclass of RuntimeException or Error is unchecked
All other Throwables are checked
Iteration
Instantiate non-static nested class (inner class) → use instance.new
Implement Iterable interface to support enhanced for loop
iterator() method must return object that implements Iterator interface
Packages
Cannot import/use/access code from default package from within different package
Access Control
Access based only on static types
Access Control w/ Inheritance & Packages
protected modifier allows package members & subclasses to use class member
Package private: no modifier → allows classes from same package, but not subclasses to access member
Access Levels
Modifier
Class
Package
Subclass
World
public
Y
Y
Y
Y
protected
Y
Y
Y
N
no modifier
Y
Y
N
N
private
Y
N
N
N
Access Control at the Top Level
Two levels: public, no modifier (package-private)
Can't declare top level class as private/protected
No such thing as a sub-package, ug.joshh.Animal & ug.joshh.Plant = 2 completely different packages
.equals()
Default implementation of .equals() uses ==
JUnit assertEquals uses .equals()
.equals() parameter must take Object, cast to actual type w/in .equals() method
Generally will need:
Reference check
null check
Class check w/ .getClass()
Cast to same type
Check fields
Asymptotics
If function has runtime $$R(N)$$ with order of growth $$\Theta(N^2)$$:
$$R(N) \in \Theta(N^2) \ \forall \text{ inputs}$$
Running function on input size of 1000 & input size of 10000 may not be large enough $$N$$ to exhibit quadratic behavior (i.e. takes 100 times longer to run)
$$\Theta$$ notation may abstract away potentially very large constant factors that may initially entirely determine the overall runtime for small inputs
Associate potential $$\Phi_i \geq 0$$ w/ $$i\text{th}$$ operation that tracks "saved up" time from cheap operations for spending on expensive ones, starting from $$\Phi_0 = 0$$
Define cost of $$i\text{th}$$ operation as $$a_i = c_i + \Phi_{i + 1} - \Phi_i$$
$$a_i = \text{deposit}$$
$$c_i = \text{withdrawal/real cost of operation}$$
$$\Phi_{i + 1} - \Phi_i = \text{total holdings}$$
On cheap operations, pick $$a_i > c_i$$ → $$\Phi$$ ↑
On expensive operations, pick $$a_i : \Phi_i > 0$$
Goals for ArrayList: $$a_i \in \Theta(1) \text{ and } \Phi_i \geq 0\ \forall\ i$$
Requires choosing $$a_i : \Phi_i > c_i$$
Cost for operations is 1 for non-powers of 2, & $$2i + 1$$ for powers of 2
For high cost ops, need $$\sim 2i + 1$$ in bank, have previous $$\frac{i}{2}$$ operations to reach balance
$$\frac{i}{2} \cdot (a_{i} - 1) - 2i \geq 0$$
$$a_{i} \geq 5$$
ArrayList amortized $$\Theta(1)$$ insertion/removal if utilizing geometric resizing
On average, each op takes constant time, arrays = good lists
Rigorously show by overestimating constant time of each operation & proving resulting potential never $$< 0$$
Disjoint Sets
Implementation
Constructor
connect
isConnected
QuickFindDS
$$\Theta(N)$$
$$\Theta(N)$$
$$\Theta(1)$$
QuickUnionDS
$$\Theta(N)$$
$$O(N)$$
$$O(N)$$
WeightedQuickUnionDS
$$\Theta(N)$$
$$O(\log{N})$$
$$O(\log{N})$$
Tree height = # of edges from root of deepest node
Root has depth 0
Weighted Quick Union
Modify quick-union to avoid tall trees
Track tree size (number of elements), also works similarly for height
Always link root of smaller tree to larger tree
Max depth of any item is $$\log{N}$$
Depth of element x only increases when tree T1 that contains x linked below other tree T2
Occurs only when weight(T2) >= weight(T1)
Size of resulting tree is at least doubled
Depth of element x incremented only when weight(T2) >= weight(T1) & resulting tree at least doubled in size
Tree containing x can double in size at most $$\log_{2}{N}$$ times, when starting from just 1 element
$$1 \cdot 2^x = N$$
$$x = \log_{2}{N}$$
Max depth starts at 0 for only 1 element (root) → increments at most $$\log_{2}{N}$$ times, $$\therefore$$ max depth = $$\log_{2}{N}$$
Path Compression
When doing isConnected(15, 10), tie all nodes seen to the root
Additional cost insignificant (same order of growth)
Kinda memoization/dynamic programming?
Path compression results in union/connected operations very close to amortized constant time
$$M$$ operations on $$N$$ nodes = $$O(N + M \lg^{*}{N})$$
Runtime$$\Theta(N)$$ b/c each new level doubles amount of work done & # of nodes visited
Exponential in height of tree, $$\Theta(2^{H})$$ → height logarithmic in # of nodes, $$H = \Theta(\log{N})$$ → overall runtime linear in # of nodes, $$\Theta(N)$$