Disclaimer: This is not a comprehensive review. It is to help you emphasize important sections, but it is your responsibility to review all previous labs and relevant chapters in the text.
-
You will be allowed to use your textbooks, and eclipse. But you will not be able to discuss with one another, use your old labs, or access the internet.
-
You will be using a temporary account created for you be the dept. Not your traditional account. Your work will be created in a new workspace in the
tmp
directory.This can be done like this:
mkdir /tmp/userName
where userName is your username(i.e. jim445434). -
The exam will contain four questions, all similar in form to previous lab exercises. Each student will have to choose three of these questions to answer.
-
The lab TA(me) will not be able to help you fix your code, I can only run your code and tell you if it passes the testing cases I have built.
-
You will print out your finished code, the TA(me again) will collect it.
-
Once your code has been tested by the TA and passes, you can consider it correct and move on to the next problem.
-
Partial credit will be given for unfinished problems.
To read user input, we must create a Scanner object.
Scanner s = new Scanner(System.in);
Note that we must specify
System.in
which tells the scanner that we will be reading from standard input(i.e. the terminal).
Once the object is created, we have an assortment of methods to read different things:
next()
: This method tokenizes the input and gives us one piece at a time.
Scanner s = new Scanner(System.in);
String s1 = s.next();
String s2 = s.next();
String s3 = s.next();
System.out.println("first thing is: " + s1);
System.out.println("next thing is: " + s2);
System.out.println("last thing is: " + s3);
If we ran this in a console:
> java test
hello there computer
first thing is: hello
next thing is: there
last thing is: computer
nextLine()
provides us with a full line of text from the console as a string
Scanner s = new Scanner(System.in);
String s1 = s.nextLine();
System.out.println("input line was: " + s1);
If we ran this in a console:
> java test
hello there computer
input line is: hello there computer
We have scanner functions to get different numeric values too. These
are nextInt()
, nextDouble
.
Creating a class involves creating private variables, getters/setters and other useful methods. Lets create an example class to describe a computer.
public class Computer {
// size of ram in gigabytes
private int ramSize;
// size of hard drive in gigabytes
private int hddSize;
// speed of cpu in gigahertz
private int cpuSpeed;
// Constructor function
public Computer(int ram, int hdd, int cpu) {
this.ramSize = ram;
this.hddSize = hdd;
this.cpuSpeed = cpu;
}
// Getters and setters
public int getRamSize() { return this.ramSize; }
public int getHddSize() { return this.hddSize; }
public int getCpuSpeed() { return this.cpuSpeed; }
public void setRamSize(int newRamSize) {
if(newRamSize > 0) {
this.ramSize = newRamSize;
}
}
public void setHddSize(int newHddSize) {
if(newHddSize > 0) {
this.hddSize = newHddSize;
}
}
public void setCpuSpeed(int newCpuSpeed) {
if(newCpuSpeed > 0) {
this.cpuSpeed = newCpuSpeed;
}
}
// One silly function to use
public boolean canCompute(int taskSize, int taskTime) {
if(taskSize < hddSize && taskTime < this.cpuSpeed*this.ramSize) {
return true;
}
return false;
}
}
There are a few points worth looking at here. We used our setters to control how people can use objects of our class type. For example, we won't let them set a negative ram size; this is a very powerful abstraction, and is the main point of getters/setters.
We also created our own constructor function. This function tells people how to create
an object. When we don't declare this one, java will automatically create a default constructor,
which takes no parameters and simply sets the private member variables to their default values, such
as 0.0
for doubles, ""
for strings etc. By making our own function public Computer(int,int,int)
we are forcing them to construct an object like this:
Computer c = new Computer(3,4,200);
If they try to use the default constructor, they will get an error
Computer c = new Computer();
If we create our own constructor function, java will not create a default constructor for us, so they won't be able to use it.
Lets create a matrix class:
public class Matrix {
private int[][] internalArray;
public Matrix(int n, int m) {
this.internalArray = new int[n][m];
}
//get the number of elements
public int getNumElts() {
return this.internalArray.length * this.internalArray[0].length;
}
public void insertValue(int value, int row, int col) {
this.internalArray[row][col] = value;
}
// Remember that giving a single index
// to a 2D array returns an entire row!
public int[] getRow(int row) {
return this.internalArray[row];
}
// Giving two index values(i.e. x[3][3])
// gives us the value at that position in the array
public int getValue(int row, int col) {
return this.internalArray[row][col];
}
// Here is our static method
public static int sumArray(int[] xs) {
int sum = 0;
for(int i = 0; i < xs.length; i++)
sum += xs[i];
return sum;
}
}
To use our non-static methods, we must create an object to call them with. This is because non-static methods can depend on internal values of the object. For example, look at our getValue method, it looks into the internalArray value at position (row, col). Each time we create an object of type Matrix, it will have its own internalArray, so we need to tell it which object's internalArray it will need to use in its calculation!.
int[] z = {1,2,3,4};
// We don't need to create an object
// we write the class name Matrix to tell
// java where our method was written
System.out.println(Matrix.sumArray(z));
Matrix m = new Matrix(3,2);
// We need an object m to call this non-static method
System.out.println(m.getNumElts());
Declaring arrays:
int[] xs = {1,2,3,4};
or
int[] xs = new int[4];
xs[0] = 1;
xs[1] = 2;
xs[2] = 3;
xs[3] = 4;
Passing an array to a function, we simply pass the name:
int[] xs = {1,2,3,4};
System.out.println( Matrix.sumArray(xs));
Declaring arrays:
int[][] xs = new int[3][4];
// fill in xs
Pretend we have these two, static, void functions
public static void simpleArray(int[] xs) {
}
public static void complexArray(int[][] xs) {
}
Passing an entire 2D array to a function:
int[][] xs = new int[3][4];
complexArray(xs);
Passing a single row of a 2D array to a function:
int[][] xs = new int[3][4];
// This passes the first row of our array to the function
simpleArray(xs[0]);
Looping through a 2D array
int[][] xs = new int[3][4];
for(int i = 0; i < xs.length; i++) {
for(int j = 0; j < xs[0].length; j++) {
System.out.println(xs[i][j]);
}
}
Remember that we use xs[0].length
to get the number of columns
in a 2d array. We use xs.length
to get the number of rows.
The number of elements is equal to the number of rows times the number of columns.
Remember the prior fact, so you don't go outside of the bounds of your array.
For our previous array, xs
, the bounds for rows are 0
to xs.length -1
and the bounds for columns are 0
to xs[0].length -1
. This is important
because our number of rows might not be equal to the number of columns, so we can't
just use xs.length
for both bound checks in our for loop.
Good luck, study hard!
--Josh