Recap from last class

Auto Boxing

  • in Java 4
Stack s = new Stack();
s.push(new Integer(3));		// wrapper class needed
Integer n = (Integer) s.pop();
  • from Java 5
Stack<Integer> s = new Stack<Integer>();
s.push(3);				    // auto boxing (auto converting int to Integer)
int n = s.pop();			// again auto boxing
s.push(new Integer(1));		// without boxing
Integer num = s.pop();		// again without boxing
s.push(2);				    // any combination
num = s.pop();			    // possible

Iterations

  • in Java 4
List strings;
/* ... */
for(int i = 0; i < strings.size(); i++) {
	String str = strings.elementAt(i);
	System.out.println(str);
}
  • or better, using an iterator
for(Iterator iter = strings.iterator(); iter.hasNext();) {
	String str = (String) iter.next();
	System.out.println(str);
}
  • from Java 5
    • this is just shorthand for the above code
List<String> strings;
/* ... */
for(String str : strings) {
	System.out.println(str);
}
 
int[] vector = new int[100];
/* ... */
int sum = 0;
for(int elem : vector) sum += elem;

Enumeration Types

  • in Java 4
    • enumeration types are implemented by using the type int
public static final int RED 	 = 0;
public static final int YELLOW	 = 1;
public static final int BLUE	 = 2;
/* ... */
switch(myColor) {
	case Color.RED:    System.out.println(”red”); break;
 	case Color.YELLOW: System.out.println(”yellow”); break;
 	case Color.BLUE:   System.out.println(”blue”); break;
};

Advantages of explicit enumeration types:

  • type safe (checked at compile time)
    • int enums don’t provide any type safety at all
  • provide a proper name space for the enumerated type
    • with int enums you have to prefix the constants to get any semblance of a name space
  • robust
    • int enums are compiled into clients, and you have to recompile clients if you ad, remove, or reorder constants
  • printed values are informative
    • if you print an int enum you just see a number
  • can be stored in collections (objects)
  • arbitrary fields and methods can be added
    • can make them more than just plain elements

New material starts

Simple Example

public enum Color {RED, YELLOW, BLUE};
/* ... */
for (Color myColor : Color.values()) System.out.println(myColor); 
  • .values() is a static method of an enumeration type, returning an array containing all values of the enum type in the order they are declared

Complex Example (Planets)

public enum Planet { 
	MERCURY (3.303e+23, 2.4397e6), 
	VENUS   (4.869e+24, 6.0518e6), 
	EARTH   (5.976e+24, 6.37814e6), 
	MARS    (6.421e+23, 3.3972e6), 
	JUPITER (1.9e+27, 7.1492e7), 
	SATURN  (5.688e+26, 6.0268e7), 
	URANUS  (8.686e+25, 2.5559e7), 
	NEPTUNE (1.024e+26, 2.4746e7), 
	PLUTO   (1.27e+22, 1.137e6); 
	
	private final double mass; // in kilograms 
	private final double radius; // in meters 
 
	Planet(double mass, double radius) { // required to initialize variables
		this.mass = mass; 
		this.radius = radius; 
	} 
	
	public double mass() { return mass; } 
	public double radius() { return radius; } 
 
	// universal gravitational constant (m3 kg-1 s-2) 
	public static final double G = 6.67300E-11; 
 
	public double surfaceGravity() { 
		return G * mass / (radius * radius); 
	} 
	
	public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity(); 
    } 
} 

Complex Example (Operations)

public enum Operation { 
	PLUS { double eval(double x, double y) { return x + y; } }, 
	MINUS { double eval(double x, double y) { return x - y; } }, 
	TIMES { double eval(double x, double y) { return x * y; } }, 
	DIVIDE { double eval(double x, double y) { return x / y; }}; 
	// Do arithmetic op represented by this constant abstract double eval(double x, double y); 
} 
 
public static void main(String args[]) { 
	double x = Double.parseDouble(args[0]); 
	double y = Double.parseDouble(args[1]); 
	for (Operation op : Operation.values()) 	System.out.printf("%f%s%f=%f%n",x,op,y,op.eval(x,y)); 
} 

Enumeration Types - UML Class Diagram

classDiagram
    class Planet {
        <<enumeration>>
        MERCURY
        VENUS
        EARTH
        MARS
        JUPITER
        SATURN
        URANUS
        NEPTUNE
        PLUTO
        + G : double ( readonly ) ( underlined )
        + mass() : double
        + radius() : double
        + surfaceGravity() : double
        + surfaceWeight(double) : double
    }

Winter leaving now, rest of lecture is with grad student

Static import

  • in Java 4
double sinus = Math.sin(Math.PI/2.0);
  • from Java 5
import static java.lang.Math.*; // import all static components from java.lang.Math
double sinus = sin(PI/2.0);
  • usage without class prefix (PI instead of Math.PI)
  • different from import java.util.*;

Lambda Expressions and Method References

In Java, a lambda expression is a concise way to define an anonymous function or a block of code that can be treated as a method argument or assigned to a variable, often used to implement functional interfaces.

Iterative Printing

Old style of an external iterator to traverse a list (before Java 8):

for (String item : items) {
	System.out.println(item)
}

New style using an internal iterator (forEach) and a lambda expression:

items.forEach(item->System.out.println(item));

Same loop using a reference to the static method println:

item.forEach(System.out::println);

Sorting an array

Arrays.sort(myPersonArray, (a,b) -> Person.compareByAge(a,b));

Same call using a reference to the static method compareByAge:

Arrays.sort(myPersonArray, Person::compareByAge);

Similar call using a reference to a method of the myComparator object:

Arrays.sort(myPersomArray, myComparator::compareByName);

Streams example

Streams offer additional features such as filters:

items.stream()
	.filter(s->s.contains("B"))
	.forEach(System.out::println);

Very fancy example using streams:

Streams.iterate(1,number -> number + 1)
	.map(number -> number * number)
	.limit(25)
	.forEach(number -> System.out.println(number + " "));

Threads

Runnable r1 = new Runnable() {
	public void run() {
		System.out.println("Old Way");
	}
}
new Thread(r1).start();

Instead of creating a Runnable object we can use a lambda expression:

new Thread(() -> System.out.println("New Way")).start();

Object Class

  • Common parent (base class)
    • Every class is extended from the Object class
  • Minimal functionality
  • Classes may override to provide specific behaviour
    • public boolean equals (Object other) {...}
    • public int hashCode() {...}
    • public String toString() {...}
    • public Class getClass() {...}
    • public Object clone() {...}

Serialization

  • Serialization is the process of transforming an object into a stream of bytes
  • Deserialization is the reverse process
public interface Serializable {};
  • Making an object serializable requires almost no effort (the interface Serializable is empty).
  • More complex operations may be necessary if, for instance, just a portion of an object’s state is to be saved on the output stream.
import java.io.*;
 
public class IntPair implements Serializable {
 
	int x;
	int y;
	
	public IntPair(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public String toString() {
		return “(" + x + "," + y + ")";
	}	
}
import java.io.*;
 
public class inout {
	 public static void main(String[] args) {
	 	IntPair p = new IntPair(2,3);
	 	try {
	 	   ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(Filename));
	 	   out.writeObject(p);
	 	   out.close();
	 	} catch(IOException e) {
	 	   e.printStackTrace();
	 	}	
	}
}
import java.io.*;
 
public class inout {
	 public static void main(String[] args) {
	 	try {
	 	   ObjectInputStream in = new ObjectInputStream( 
			new FileInputStream(Filename));
	 	   IntPair p = (IntPair) in.readObject();
	 	   System.out.println(p);
	 	} catch(Exception e) {
	 	   e.printStackTrace();
	 	}	
	}
}

Some useful interfaces

  • interface Serializable {}
  • interface Cloneable {}
    • this interface does not include the clone method
    • a class implements the Cloneable interface to indicate ot the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class
interface Comparable<T> {
	public int compareTo(T o)
}
  • interface Comparable<T> {}
    • imposes a total ordering on the objects of each class that implements it
    • compareTo(T o) returns a negative integer, zero or a positive integer as this object is less than, equal to, or greater than the specified object
interface Comparator<T> {
	public int compare(T o1, To2)
}
  • interface Comparator<T> {}
interface Predicate<T> {
	Predicate<T> and(Predicate<? super T> other);
	Predicate<T> or(Predicate<? super T> other);
	Predicate<T> negate();
}

End of lecture 3