Midterm 1
Grade in 61A | Mean | N |
C or lower | 5.2 | 19 |
C+ | 8.5 | 10 |
B- | 11.16 | 48 |
B | 13.57 | 68 |
B+ | 18.03 | 75 |
A- | 23.28 | 40 |
A | 27.07 | 38 |
A+ | 34.4 | 4 |
Grade in 61A | Mean | N |
C or lower | 11.78 | 6 |
C+ | 30.74 | 1 |
B- | 11.54 | 7 |
B | 16.84 | 18 |
B+ | 23.59 | 38 |
A- | 27.68 | 54 |
A | 32.32 | 69 |
A+ | 35.62 | 25 |
Students with no prior Java experience (1/5)
Students with 4/5 or 5/5 prior Java experience
Midterm 1
Prior Java Experience | Mean | N |
1 | 14.71 | 191 |
2 | 17.23 | 78 |
3 | 18.64 | 59 |
4 | 20.44 | 27 |
5 | 20.23 | 36 |
Students with a B-, B, or B+ in 61A
Students with a A-, A, or A+ in 61A
Prior Java Experience | Mean | N |
1 | 25.58 | 82 |
2 | 25.36 | 39 |
3 | 27.74 | 43 |
4 | 30.31 | 57 |
5 | 31.73 | 91 |
Prior Sem.
Fall 2014: 17 points
Spring 2015: 35 points
Spring 2016: 40 points
Overall
Fairly happy with the midterm, but there were not enough C-level problems.
Test score shadowing exists.
Spring 2016: 40 points
Announcements Lec 13, 14, 15
Next 3 lectures are various bits of Java syntax, less of a coherent story.
HW1: Chance to get more practice with the topics in lectures 12-15.
CS61B, Spring 2015
Lecture 13: Generics, Conversion, Promotion
Generics
For the most part, using generics is pretty straightforward.
import java.util.ArrayList;��public class BasicArrayList {� public static void main(String[] args) {� ArrayList<String> L = new ArrayList<String>();� L.add("potato");� L.add("ketchup");
String first = L.get(0);�}
}
actual type argument: String.
Primitives Cannot Be Used as Actual Type Arguments
We cannot use primitive types as actual type arguments.
import java.util.ArrayList;��public class BasicArrayList {� public static void main(String[] args) {� ArrayList<int> L = new ArrayList<int>();� L.add(5);� L.add(6);
int first = L.get(0);�}
}
jug ~/temp
$ javac BasicArrayList.java
BasicArrayList.java:5: error: unexpected type
ArrayList<int> L = new ArrayList<int>();
^
required: reference
found: int
Reference Types
Reminder: Java has 8 primitive types. All other types are reference types.
For each primitive type, there is a corresponding reference type called a wrapper class.
Reference Types as Actual Type Arguments
Solution: Use wrapper type as actual type parameter instead of primitive type.
Conversion between int and Integer is annoying, so in Java 1.5 they introduced...
import java.util.ArrayList;��public class BasicArrayList {� public static void main(String[] args) {� ArrayList<Integer> L = new ArrayList<Integer>();� L.add(new Integer(5));� L.add(new Integer(6));
int first = L.get(0).valueOf();�}
}
Autoboxing
Autoboxing (auto-unboxing): Implicit conversions between wrapper/primitives.
Code above works even though we’re passing an int into an Integer parameter, and assigning a return value of type Integer to an int.
import java.util.ArrayList;��public class BasicArrayList {� public static void main(String[] args) {� ArrayList<Integer> L = new ArrayList<Integer>();� L.add(5);� L.add(6);
int first = L.get(0);�}
}
Autoboxing and Unboxing
Wrapper types and primitives can be used almost interchangeably.
Some notes:
public static void blah(Integer x) {
System.out.println(x);
}
int x = 20;
blah(x);
public static void blahPrimitive(int x) {
System.out.println(x);
}
Integer x = new Integer(20);
blahPrimitive(x);
Wrapper Types Are (Mostly) Just Like Any Class
You can read the source code to all built-in Java libraries.
public final class Integer
extends Number implements Comparable<Integer> {
private final int value;
public Integer(int value) {
this.value = value;
}
...
}
Wrapper Type Memory (PollEv.com/jhug text JHUG to 37607?)
Assuming:
How much total memory is used by bleepblorp to store its local variables?
public static void bleepblorp() {
Integer x = new Integer(5);
System.out.println(x);
}
Related Concept: Promotion
A similar thing happens when moving from a primitive type with a narrower range to a wider range.
To move from a wider format to a narrower format, must use casting:
Full details here: http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html
public static void blahDouble(double x) {
System.out.println(“double: “ + x);
}
int x = 20;
blahDouble(x);
public static void blahInt(int x) {
System.out.println(“int: “ + x);
}
double x = 20;
blahInt((int) x);
Immutability
Immutable Data Types
An immutable data type is one for which an instance cannot change in any observable way after instantiation.
Examples:
The final keyword will help the compiler ensure immutability.
Immutability
Advantage: Less to think about: Avoids bugs and makes debugging easier.
Disadvantage: Must create a new object anytime anything changes.
Warning: Declaring a reference as Final does not make object immutable.
charAt(int i)
compareTo(String s)
concat(String s)
split(String r)
String
Defining Generic Classes
Goals
Goal 1: Create a class ArrayMap with the following methods:
Ok to ignore resizing for this exercise.
ArrayMap.java
ArrayMap (Basic Implementation)
Array implementation of a Map:
public class ArrayMap<K, V> {
private K[] keys;
private V[] values;
private int size;
public ArrayMap() {
keys = (K[]) new Object[100];
values = (V[]) new Object[100];
size = 0;
}
...
}
ArrayMap (Basic Implementation)
public void put(K key, V value) {
int i = getKeyIndex(key);
if (i > -1) {
values[i] = value; return; }
keys[size] = key;
values[size] = value;
size += 1;
}
public V get(K key) {
return values[findKey(key)];
}
public boolean
containsKey(K key) {
int i = findKey(key);
return (i > -1);
}
public K[] keys() {
return keys;
}
Using An ArrayMap
ArrayMap<Integer, String> ismap = new ArrayMap<Integer, String>();
ismap.put(5, "hello");
ismap.put(10, "ketchup");
public class ArrayMap<K, V> {
private K[] keys;
private V[] values;
private int size;
public ArrayMap() {
keys = (K[]) new Object[100];
values = (V[]) new Object[100];
size = 0;
}
...
Actual type arguments
Generic type variables
A Mysterious Error Appears
The Issue:
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2));�}
$ javac ArrayMapTest.java
ArrayMapTest.java:11: error: reference to assertEquals is ambiguous
assertEquals(expected, am.get(2));
^
both method assertEquals(long,long) in Assert and method assertEquals(Object,Object) in Assert match
PollEv.com/jhug or text JHUG to 37607
Which automatic translations are needed to call assertEquals(double, double)?
Hint, the actual call is: assertEquals(int, Integer)
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2));�}
There may be more than one right answer.
PollEv.com/jhug or text JHUG to 37607
Which automatic translations are needed to call assertEquals(double, double)?
Hint, the actual call is: assertEquals(int, Integer)
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2));�}
There may be more than one right answer.
Open Question
What automatic translations are needed to call assertEquals(Object, Object)?
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2)); }
Open Question
What automatic translations are needed to call assertEquals(Object, Object)?
Only one thing:
Even though this is ‘easier’ than the 3-step process needed to get to assertEquals(double, double), it’s still ambiguous and thus Java won’t let the code above compile.
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2)); }
Open Question
How do we get the code to compile, e.g. how do we resolve the ambiguity?
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2)); }
Open Question
How do we get the code to compile?
Many possible answers, one of them is:
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals(expected, am.get(2)); }
@Test�public void test() {� ArrayMap<Integer, Integer> am = new ArrayMap<Integer, Integer>();� am.put(2, 5);� int expected = 5;� assertEquals((Integer) expected, am.get(2)); }
Generic Methods
Goals
Goal: Create a class MapHelper with three methods:
Goals
Goal: Create a class MapHelper with three methods:
MapHelper.java
Generic Methods
Can create a method that operates on generic types by defining type parameters before the return type of the method:
In almost all circumstances, using a generic method requires no special syntax:
public static <X, Zerp> Zerp get(ArrayMap<X, Zerp> am, X key) {
if (am.containsKey(key)) {
return am.get(key);
}
return null;
}
Formal type parameter definitions.
Return type: Zerp (whatever that is)
ArrayMap<Integer, String> ismap =
new ArrayMap<Integer, String>();
System.out.println(MapHelper.get(ismap, 5));
It’s that easy.
Goals
Goal: Create a class MapHelper with three methods:
to be continued...
MapHelper.java
Citations
Drink:
Wrapper class image from Nanyang Technological University: https://www3.ntu.edu.sg/home/ehchua/programming/java/images/OOP_WrapperClass.png