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
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.
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>[]
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
If you want to master the more advanced aspects of Java, I enjoyed:
Can access digital versions of both for free through UH Library, but only 4 users at a time.
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(0)) //first PyramidStack<Meep> (shafts.get(0).peek()) //Top of that stack: a Meep (shafts.get(0).peek().compareTo(newcomer)) //an int
if (shafts.get(0).peek().compareTo(newcomer) < 0) { //top meep is smaller
if (shafts.get(0).peek().compareTo(newcomer) < 0) { //top meep is smaller
Now we have 3 stacks in shafts, but what if stack at shaft.get(0) is empty? Crash!
if (shafts.get(0).size() > 0 && shafts.get(0).peek().compareTo(newcomer) < 0) { //...
if (shafts.get(0).size() == 0 || shafts.get(0).peek().compareTo(newcomer) < 0) { //newcomer can move to first shaft