return(x); //NO: looks like method call return (x); //BETTER... space at least (same with if/for/etc) return x; //YES return x > 0 && y > 0; //fine return (x > 0 && y > 0); //now parentheses might be worth it
boolean negative = ... //NO: == is error prone (too easy to put =) if (negative == true) { //just use: if (negative) { return true; }
//NO: if test == true, return true; if test == false; return false if (x < 0 && y < 0) { return true; }else { return false; } //instead: just return test;
if (x < 0) { //...do this stuff... }else { //NO: elses are optional for a reason }
if (x < 0) { //...do this stuff... }else if (x >= 0) { //NO: use else here //...do this other stuff... }
if (array.length > 0) { for (int i = 0; i < array.length; i++) { //...do stuff... } } //(maybe need if doing stuff in if but outside loop) //(but not in simple case like this)
Method names not as standardized as for stack
Queue<Integer> q = new Queue<Integer>(); q.offer(4); q.offer(7); q.offer(9); System.out.println(q.size()); // 3 System.out.println(q.peek()); // 4 q.poll(); System.out.println(q.poll()); // 7
public class Queue<E> {
private static final int CAPACITY = 5;
private E[] items;
private int front; //points at first item
private int back; //first blank spot
public Queue() {
//use one extra cell so never full, so front == back always means empty
@SuppressWarnings("unchecked") //more on this later...
E[] array = (E[]) new Object[CAPACITY + 1];
items = array;
back = 0;
front = 0;
}
public void offer(E item) {
if (this.size() == CAPACITY) {
//Implementation-level restriction: would be nice to avoid this...
throw new IllegalStateException("Queue is full.");
}
this.items[back] = item;
this.back = (this.back + 1) % items.length;
}
public E peek() {
if (this.size() == 0) {
throw new IllegalStateException("Queue is empty.");
}
return this.items[front];
}
public E poll() {
E item = this.peek(); //throws exception if empty
this.front = (this.front + 1) % items.length;
return item;
}
public int size() {
return (this.back + items.length - this.front) % items.length;
}
}
Big-Os?
null
when queue is empty
class Queue<E> { private ArrayList<E> items; public Queue() { items = new ArrayList<E>(); } public void offer(E item) { items.add(item); } public E peek() { if (items.isEmpty()) { throw new IllegalStateException("Cannot poll from empty queue."); } return items.get(0); } public E poll() { E item = this.peek(); //will throw exception if needed items.remove(0); return item; } public int size() { return items.size(); } }
ADT behavior vs efficiency
Also before autoboxing
public static void main(String[] args) { ArrayList numbers = new ArrayList(); numbers.add(new Integer(2)); numbers.add(new Integer(4)); numbers.add(new Integer(5)); int total = product(numbers); System.out.println(total); } public static int product(ArrayList nums) { int product = 1; for (int i = 0; i < nums.size(); i++) { Integer n = (Integer) nums.get(i); //nums.get(i) returns an Object product *= n.intValue(); } return product; }
(Still no autoboxing in this example)
public static void main(String[] args) { ArrayList<Integer> numbers = new ArrayList<Integer>(); numbers.add(new Integer(2)); numbers.add(new Integer(4)); numbers.add(new Integer(5)); int total = product(numbers); System.out.println(total); } public static int product(ArrayList<Integer> nums) { int product = 1; for (int i = 0; i < nums.size(); i++) { Integer n = nums.get(i); //no cast; returns Integer now product *= n.intValue(); } return product; }
Autoboxing, for-each loop
public static void main(String[] args) { ArrayList<Integer> numbers = new ArrayList<Integer>(); numbers.add(2); numbers.add(4); numbers.add(5); int total = product(numbers); System.out.println(total); } public static int product(ArrayList<Integer> nums) { int product = 1; for (int n : nums) { product *= n; } return product; }
Still general purpose: Can insert any kind of object
class Queue { //no <E> private static final int CAPACITY = 5; private Object[] items; private int front; //points at first item private int back; //first blank spot public Queue() { Object[] array = new Object[CAPACITY + 1]; items = array; back = 0; front = 0; } public void offer(Object item) { if (this.size() == CAPACITY) { //Implementation-level restriction: would be nice to avoid this... throw new IllegalStateException("Queue is full."); } this.items[back] = item; this.back = (this.back + 1) % items.length; } public Object peek() { if (this.size() == 0) { throw new IllegalStateException("Queue is empty."); } return this.items[front]; } public Object poll() { Object item = this.peek(); //throws exception if empty this.front = (this.front + 1) % items.length; return item; } public int size() { return (this.back + items.length - this.front) % items.length; } }
public static void main(String[] args) { Queue q = new Queue(); q.offer("here"); q.offer("there"); q.offer(4.3); //autoboxed -> Integer -> Object //... while (q.size() > 0) { Object o = q.poll(); //every thing comes out as Object String str = (String) o; //need to cast back to what you put in -> System.out.println(str.length()); // crash: ClassCastException } }
class Queue<E> { private static final int CAPACITY = 5; private E[] items; private int front; private int back; public Queue() { this.items = new E[CAPACITY]; //NO! Does not compile this.front = 0; this.back = 0; } }
Compiler can't put a specific E here: Integer, String, what? Needs one type that works for all Stack uses.
E example = new E(); //NO: which constructor would get called? public E[] snapshot() { return items; //NO: Object[]? //But (new Queue<String>()).snapshot() should give String[] //and (new Queue<Integer>()).snapshot() should give Integer[] }
this.items = new E[CAPACITY]; //NO! Does not compile this.items = new Object[CAPACITY]; //NO! E[] != Object[] this.items = (E[]) new Object[CAPACITY]; //Works... but warning
@SuppressWarnings("unchecked") E[] array = (E[]) new Object[CAPACITY]; this.items = array;
ArrayList<String>[] strMatrix = new ArrayList<String>[10]; //NO!
ArrayList<Integer> nums = new ArrayList<Integer>(); nums.add(3); Object[] matrix = strMatrix; //because ArrayList[] is a kind of Object[] matrix[0] = nums; //because an ArrayList is an Object strMatrix[0].get(0); //OOPS! Just got an Integer out of ArrayList<String>[]
new E()
or new E[size]
PyramidStack<Meep>[] shafts = new PyramidStack<Meep>[3]; //NO! Can't. shafts[0] = new PyramidStack<Meep>();
ArrayList<PyramidStack<Meep>> shafts = new ArrayList<PyramidStack<Meep>>(); shafts.add(new PyramidStack<Meep>());
More info: Java Tutorial, Arrays in Java Generics
Given:
ArrayList<PyramidStack<Meep>> shafts = new ArrayList<PyramidStack<Meep>>(); //... add three new PyramidStack<Meep>()s Meep newcomer = new Meep(5); //Meeps are Comparable, so has compareTo method.
Problem: See if meep on top of left shaft (index: 0) is smaller than newcomer
(shafts) //whole ArrayList (shafts.get(2)) //first PyramidStack<Meep> (shafts.get(2).peek()) //Top of that stack: a Meep (shafts.get(2).peek().compareTo(newcomer)) //an int
if (shafts.get(2).peek().compareTo(newcomer) < 0) { //top meep is smaller
if (shafts.get(2).peek().compareTo(newcomer) < 0) { //top meep is smaller
Now we have 3 stacks in shafts, but what if stack at shaft.get(2) is empty? Crash!
if (shafts.get(2).size() > 0 && shafts.get(2).peek().compareTo(newcomer) < 0) { //...
if (shafts.get(2).size() == 0 || shafts.get(2).peek().compareTo(newcomer) < 0) { //newcomer can move to first shaft