HW 0: A Java Crash Course

HW Goals #

In this assignment, we will go through basic Java syntax concepts. While this assignment is optional and you will not submit your answers, it is highly recommended for those with no prior Java experience. The lectures will NOT cover this material explicitly, though you are expected to understand it.

This tutorial assumes that you have significant (one semester) experience with at least some programming language, and is intended only to highlight the Java way of doing some previously familiar things.

While we hope this document should stand alone for the curious and self-motivated student, you may find it helpful to read the suggested supplementary reading when provided.

Feel free to skim and read at whatever pace you feel comfortable with. It is OK to skip parts of this HW. Use your best judgment. The directions are a bit more verbose than is probably necessary.

A Basic Program #

In Lab 1, we’ll learn how to run Java code on your computer. Since lab 1 hasn’t happened yet, we’ll instead use an in-browser Java compiler for this HW only: the Java Visualizer.

public class OurFirstProgram {
    public static void main(String[] args) {
        int x = 5;
        x = x + 1;
        System.out.println(x);
        int y = x;
        x = x + 1;
        System.out.println("x is: " + x);
        System.out.println("y is: " + y);
    }
}
Values and variables

There sure is a lot of weird stuff here, like public class and public static void main(String[] args). We’ll discuss these in more detail later, but for this HW, you should ignore all of these mysterious incantations.

Click on the Forward > link twice so that you’re on “Step 3 of 9”. You’ll see an x appear in a blue box the right with the value 5 once the line int x = 5 is executed. Perhaps unsurprisingly, this statement assigns the value 5 to the variable x.

Unlike other programming languages (like Python, Scheme, and MATLAB), Java variables have a static type. By this, we mean that x will only ever be able to store an integer. If you tried to put a number like 5.3 into it, the code would fail.

Also unlike these other languages, every statement in Java must be followed by a semicolon. The semicolon is very important, as it tells Java where one statement ends and another begins.

Click forward again (4 of 9), and you’ll see that the value of x has changed to 6. Click forward one more time (5 of 9), and you’ll see that x is printed in the Program output box below using the rather verbose command name System.out.println. Yes, this is really how you print in Java.

Ordinarily, when you write Java programs, you won’t be able to see into your program’s brain (i.e. there will be no blue box listing all the variables). However, this visualizer is a pedagogical tool that makes such brain scanning possible.

Click forward until the program completes execution. Everything should behave more or less as you’d expect, based on the previous lines. If anything surprises you, post your questions on the course forum!

Try editing the code and running it again. Experiment and see what happens as you tweak the program. If you have interesting observations or any questions arise, post them on the course forum. Maybe try assigning a real number (e.g. 3.3) and see what occurs (we promise your computer won’t explode).

Boolean Expressions and if #

Optional Supplementary Reading: Shewchuk

Basic Conditionals #

Now open up the below program in the visualizer:

public class Conditionals {
    public static void main(String[] args) {
        int x = 5;

        if (x < 10)
            x = x + 10;

        if (x < 10)
            x = x + 10;

        System.out.println(x);
    }
}
Conditional statements

Step forward until the program completes and observe the flow of the program. The if statement in java checks the condition that you put inside parentheses, and if the result is true (if the condition is met), it executes the next statement below.

Boolean Operators #

Equality and Relational Operators #

The equality and relational operators determine if one operand is greater than, less than, equal to, or not equal to another operand.

==
equal to
!=
not equal to
>
greater than
>=
greater than or equal to
<
less than
<=
less than or equal to

The way that we’ve defined the operators here only holds true for numbers. We’ll revisit some of these operations later and define how they work for other kinds of data as well.

A common mistake is to use = (assignment) instead of == when testing if two numbers are equal.

Negation #

The value of a boolean expression can also be negated using the ! operator, similar to how not in Python works.

public class Negation {
    public static void main(String[] args) {
        int x = 5;

        System.out.println(x == 5);
        System.out.println(!(x == 5));
    }
}
Negation

Note that the expression needs to be parenthesized to say, “take the result of evaluating x == 5 and negate it.”

Conditional Operators #

Boolean expressions can be combined with the || conditional-OR and && conditional-AND operators. These are equivalent to Python’s or and and operators.

public class LogicalOperators {
    public static void main(String[] args) {
        int x = 5;
        int y = 10;

        if (x < 10 && y > 5)
            System.out.println(x + y);
    }
}
Logical operators

For more complex expressions, we’ll want to make sure Java gets the order of operations right by introducing extra parentheses. Add parentheses and negation operators to the conditional expression below so that the program executes the print statement.

public class LogicalOperators {
    public static void main(String[] args) {
        int x = 5;

        if (x + 1 > 6 && x * x != 25 || x + 5 < 10 && x / 2 > 0)
            System.out.println(x);
    }
}
Logical operators practice

Boolean expressions also short-circuit following the same rules as languages like Python. That is, Java evaluates expressions approximately left-to-right. If it determines that it knows the value of the entire expression, (e.g. part of an OR is true, or part of an AND is false) it won’t evaluate the other parts, because it already knows the answer!

This is particularly important if part of a boolean expression is a function – that function may not get called!

Curly Braces (and Conditionals) #

It is also possible to execute multiple statements in response to a single condition. We do this by wrapping the statements in curly braces.

public class ConditionalsWithBlocks {
    public static void main(String[] args) {
        int x = 5;

        if (x < 10) {
            System.out.println("I shall increment x by 10.");
            x = x + 10;
        }

        if (x < 10) {
            System.out.println("I shall increment x by 10.");
            x = x + 10;
        }

        System.out.println(x);
    }
}
Conditional statements with blocks

Curly braces are very important in Java! Unlike Python, statements are grouped by braces, and not by indentation. For an example of how this can go terribly wrong, try running the following program, which is supposed to print the absolute value of x. Then try changing the value of x to a positive number. Run it and make sure you understand why things go wrong.

public class PrintAbsoluteValue {
    public static void main(String[] args) {
        int x = -5;

        if (x < 0)
            System.out.println("I should negate X");
            x = -x;

        System.out.println(x);
    }
}
Missing curly braces

Unlike Python, most whitespace including indentation does not matter with regards to the functionality of your program. In fact, you can get away with replacing every whitespace in your entire program with a single space (given that semicolons are the separators between statements), though this is a horrible idea and we will be very sad if you write programs like the following valid Java program:

public class OurFirstProgram { public static void main(String[] args) { int x = 5; if (x < 10) { System.out.println("I shall increment x by 10."); x = x + 10; } if (x < 10) { System.out.println("I shall increment x by 10."); x = x + 10; } System.out.println(x); } }

Curly Brace Standards #

There are two common styles for curly braces:

if (x > 5) {
    x = x + 5;
}

and,

if (x > 5)
{
    x = x + 5;
}

Which of these two styles is a bit of a holy war. In this course, however, we will stick to the first convention. Note that, in this example, we’ve wrapped curly braces around a single statement, which isn’t required in Java. In this course, we’ll always use curly braces, even if we have only one statement to execute. This is to avoid bugs, especially if we edit the code later. Don’t fret too much about these little details, the style checker will tell you if you do something different from what we expect.

For more than you ever wanted to know about indentation styles, see the Wikipedia article on Indent style.

else #

The else keyword allows you to specify behavior that should occur if an if block does not execute.

public class ElseStatements {
    public static void main(String[] args) {
        int x = 9;
        if (x - 3 > 8) {
            System.out.println("x - 3 is greater than 8");
        } else {
            System.out.println("x - 3 is not greater than 8");
        }
    }
}
Else statement

We can also chain else statements (similar to elif in Python).

public class ChainedElseStatements {
    public static void main(String[] args) {
        int dogSize = 20;
        if (dogSize >= 50) {
            System.out.println("woof!");
        } else if (dogSize >= 10) {
            System.out.println("bark!");
        } else {
            System.out.println("yip!");
        }
    }
}
Chained if-else

Note that in the code above, we used >=, which means greater than or equal.

while #

Optional Supplementary Reading: Shewchuk

The while keyword lets you repeat a block of code as long as some condition is true.

public class Bottles {
    public static void main(String[] args) {
        int bottles = 99;
        while (bottles > 0) {
            System.out.println(bottles + " bottles of beer on the wall.");
            bottles = bottles - 1;
        }
    }
}
While loops

Try running this program, and watch what happens. Note that as soon as the code inside curly braces is completed, we head straight back to the while condition.

Optionally, experiment a bit: Try and see what happens if you start bottles off at -4. Also try and see what happens if you remove the line: bottles = bottles - 1;

Important note: You should think of your program as running in order, line by line. If the condition becomes false in the middle of the loop, the code does not simply stop. So for example, the program below will print “-312 bottles of beer on the wall.” even though -312 is not greater than 0 and the condition became false.

public class Bottles5 {
    public static void main(String[] args) {
        int bottles = 5;
        while (bottles > 0) {
            bottles = -312;
            System.out.println(bottles + " bottles of beer on the wall.");
        }
    }
}
While loops run line-by-line

doubles and Strings #

So far, all of our variables have been of type int. There are many other types that you can use in Java. Two examples of these are double and String. double stores approximations of real numbers, and String stores strings of characters. The program below simulates a race between Achilles and a Tortoise. Achilles is twice as fast, so he should overtake the Tortoise (who has a head start of 100 distance units).

public class AchillesTortoise {
    public static void main(String[] args) {
        String a = "Achilles";
        String t = "Tortoise";
        double aPos = 0;
        double tPos = 100;
        double aSpeed = 20;
        double tSpeed = 10;
        double totalTime = 0;
        while (aPos < tPos) {
            System.out.println("At time: " + totalTime);
            System.out.println("    " + a + " is at position " + aPos);
            System.out.println("    " + t + " is at position " + tPos);

            double timeToReach = (tPos - aPos) / aSpeed;
            totalTime = totalTime + timeToReach;
            aPos = aPos + timeToReach * aSpeed;
            tPos = tPos + timeToReach * tSpeed;
        }
    }
}
Achilles vs. the Tortoise

Creative Exercise 1a: Drawing a Triangle #

Finally! A chance to do something on your own.

Your goal is to create a program that prints the following figure. Your code should use loops (i.e. shouldn’t just be five print statements, that’s no fun).

*
**
***
****
*****

Here’s a skeleton to get you started:

public class DrawTriangle {
    public static void main(String[] args) {
        // Add code here!
    }
}
Triangle skeleton

Write this code by copy-pasting the below lines of code into the above skeleton. Some lines may be used once, multiple times, or not at all.

col = col + 1;
int col = 0;
int row = 0;
int SIZE = 5;
row = row + 1;
System.out.print('*');    // Print a single *
System.out.println('*');  // Print a single *, and start a new line
System.out.println();     // Start a new line
while (col <= row) {
while (col < row) {
while (row < SIZE) {
while (row <= SIZE) {
}

You may find System.out.print to be a useful alternative to System.out.println. The difference is that System.out.print does not include an automatic newline at the end.

Run your code and verify that it works correctly by comparing it by eye to the program above. In lab, we’ll discuss more sophisticated ways of verifying program correctness.

Save your code someplace (say by emailing it to yourself), as you’ll need it again soon.

Defining Functions (a.k.a. Methods) #

The following four pieces of code are all equivalent in Python, MATLAB, Scheme, and Java. Each defines a function that returns the maximum of two values and then prints the maximum of 5 and 15.

Python Function #

def max(x, y):
    if (x > y):
        return x
    return y

print(max(5, 15))

MATLAB Function #

function m = max(x, y)
    if (x > y)
        m = x
    else
        m = y
    end
end

disp(max(5, 15))

Scheme Function #

(define max (lambda (x y) (if (> x y) x y)))
(display (max 5 15)) (newline)

Java Function #

public static int max(int x, int y) {
    if (x > y) {
        return x;
    }
    return y;
}
public static void main(String[] args) {
    System.out.println(max(10, 15));
}

Functions in Java, like variables, have a specific return type. The max function has a return type of int (indicated by the word int right before the function name). Also functions in Java are called methods, so we’re going to start calling them that from this moment.

We refer to the entire string public static int max(int x, int y) as the method’s declaration, as it lists the parameters, return type, name, and any modifiers. Here our modifiers are public and static, though we won’t learn what these mean for a few days.

For this homework, all methods are going to have public static at the front of their signature. Just accept this for now. We’ll talk more about this in a future lecture and lab.

Creative Exercise 1b: drawTriangle #

public class DrawTriangleMethod {
    public static void main(String[] args) {
        // Add code here!
    }
    // And here!
}
Triangle skeleton

Starting from the same skeleton for drawing a triangle as we used before, create a program with one additional method (in addition to the existing main).

Name this new method drawTriangle, make it public static, and give it a return type of void (this means that it doesn’t return anything at all).

The drawTriangle method should take one int parameter named N, and it should print out a triangle exactly like your triangle from Exercise 1a, but N asterisks tall instead of 5.

After writing drawTriangle, modify the main function so that it calls drawTriangle with N = 10.

Depending on your programming background, you may find this task quite challenging. We encourage you to work with others or post on the course forum.

If you’re just confused about where to start, try adapting the code from the example for max in Java above and rename the function drawTriangle and change its return type from int to void.

Arrays #

Optional Supplementary Reading: Shewchuk

Our final new syntax item of this HW is the array. Arrays are like vectors in Scheme, lists in Python, and arrays in MATLAB.

The following four programs in Python, MATLAB, Scheme, and Java declare a new array of the integers 4, 7, and 10, and then prints the 7.

Python Array #

numbers = [4, 7, 10]
print(numbers[1])

MATLAB Array #

numbers = [4 7 10]
disp(numbers(2))

Scheme Array #

(define numbers #(4 7 10))
(display (vector-ref numbers 1)) (newline)

Java Array #

int[] numbers = new int[3];
numbers[0] = 4;
numbers[1] = 7;
numbers[2] = 10;
System.out.println(numbers[1]);

Or in an alternate (but less general) shorthand:

Alternate Java Array #

int[] numbers = new int[]{4, 7, 10};
System.out.println(numbers[1]);

You can get the length of an array by using .length, for example, the following code would print 3:

int[] numbers = new int[]{4, 7, 10};
System.out.println(numbers.length);

Exercise 2 #

Using everything you’ve learned so far on this homework, you’ll now create a function with the signature public static int max(int[] m) that returns the maximum value of an int array. You may assume that all of the numbers are greater than or equal to zero.

Modify the the code below so that max works as described. Furthermore, modify main so that the max method is called on the given array and its max printed out (in this case, it should print 22).

public class ArrayMax {
    /** Returns the maximum value from arr. */
    public static int max(int[] arr) {
        return 0;
    }
    public static void main(String[] args) {
        int[] numbers = new int[]{9, 2, 15, 2, 22, 10, 6};
    }
}
Exercise 2

For Loops #

Consider the function below, which sums the elements of an array.

public class ArraySum {
    /** Uses a while loop to sum a. */
    public static int whileSum(int[] a) {
      int i = 0; // initialization
      int sum = 0;
      while (i < a.length) { // termination
            sum = sum + a[i];
            i = i + 1; // increment
      }
      return sum;
    }
}

Programmers in the 1950s observed that it was very common to have code that featured initialization of a variable, followed by a loop that begins by checking for a termination condition and ends with an increment operation. Thus was born the for loop.

The sum function below uses a basic for loop to do the exact same job of the whileSum function above.

public class ArraySum {
    /** Uses a basic for loop to sum a. */
    public static int sum(int[] a) {
        int sum = 0;
        for (int i = 0; i < a.length; i = i + 1) {
            sum = sum + a[i];
        }
        return sum;
    }
}
for loop array sum

In Java, the for keyword has the syntax below:

for (initialization; termination; increment) {
    // statements
}

The initialization, termination, and increment must be semicolon separated.

Exercise 3 #

Rewrite your solution to Exercise 2 so that it uses a for loop.

public class ArrayMax {
    /** Returns the maximum value from m using a for loop. */
    public static int forMax(int[] m) {
        return 0;
    }
    public static void main(String[] args) {
        int[] numbers = new int[]{9, 2, 15, 2, 22, 10, 6};
    }
}
Exercise 3

Break and Continue #

Occasionally, you may find it useful to use the break or continue keywords. The continue statement skips the rest of the current iteration of the loop, effectively jumping straight to the increment condition.

For example, the code below prints each String from an array three times, but skips any strings that contain “horse”.

public class ContinueDemo {
    public static void main(String[] args) {
        String[] a = {"cat", "dog", "laser horse", "ketchup", "horse", "horbse"};
        for (int i = 0; i < a.length; i += 1) {
            if (a[i].contains("horse")) {
                continue;
            }
            for (int j = 0; j < 3; j += 1) {
                System.out.println(a[i]);
            }
        }
    }
}
continue keyword

By contrast, the break keyword completely terminates the innermost loop when it is called. For example the code below prints each String from an array three times, except for strings that contain horse, which are only printed once.

public class BreakDemo {
    public static void main(String[] args) {
        String[] a = {"cat", "dog", "laser horse", "ketchup", "horse", "horbse"};
        for (int i = 0; i < a.length; i += 1) {
            for (int j = 0; j < 3; j += 1) {
                System.out.println(a[i]);
                if (a[i].contains("horse")) {
                    break;
                }
            }
        }
    }
}
break keyword

break and continue also work for while loops.

Optional Exercise 4 #

This is a particularly challenging exercise, but strongly recommended.

Write a function windowPosSum(int[] a, int n) that replaces each element a[i] with the sum of a[i] through a[i + n], but only if a[i] is positive valued. If there are not enough values because we reach the end of the array, we sum only as many values as we have.

For example, suppose we call windowPosSum with the array a = {1, 2, -3, 4, 5, 4}, and n = 3. In this case, we’d:

  • Replace a[0] with a[0] + a[1] + a[2] + a[3].
  • Replace a[1] with a[1] + a[2] + a[3] + a[4].
  • Not do anything to a[2] because it’s negative.
  • Replace a[3] with a[3] + a[4] + a[5].
  • Replace a[4] with a[4] + a[5].
  • Not do anything with a[5] because there are no values after a[5].

Thus, the result after calling windowPosSum would be {4, 8, -3, 13, 9, 4}.

As another example, if we called windowPosSum with the array a = {1, -1, -1, 10, 5, -1}, and n = 2, we’d get {-1, -1, -1, 14, 4, -1}.

public class BreakContinue {
    public static void windowPosSum(int[] a, int n) {
        /** your code here */
    }
    public static void main(String[] args) {
        int[] a = {1, 2, -3, 4, 5, 4};
        int n = 3;
        windowPosSum(a, n);
        // Should print 4, 8, -3, 13, 9, 4
        System.out.println(java.util.Arrays.toString(a));
    }
}
Exercise 4 starter code

Starter code is available at this link.

Hint 1: Use two for loops.

Hint 2: Use continue to skip negative values.

Hint 3: Use break to avoid going over the end of the array.

The Enhanced For Loop #

Java also supports iteration through an array using an “enhanced for loop”. There are many circumstances where we don’t actually care about the index at all, but only the element we’re looking at. In this case, we avoid creating an index variable using a special syntax involving a colon.

For example, in the code below, we do the exact thing as in BreakDemo above. However, in this case, we do not create an index i. Instead, the String s takes on the identity of each String in a exactly once, starting from a[0], all the way up to a[a.length - 1]. You can try out this code at this link.

public class EnhancedForBreakDemo {
    public static void main(String[] args) {
        String[] a = {"cat", "dog", "laser horse", "ketchup", "horse", "horbse"};
        for (String s : a) {
            for (int j = 0; j < 3; j += 1) {
                System.out.println(s);
                if (s.contains("horse")) {
                    break;
                }
            }
        }
    }
}
Enhanced for loop
Last built: 2022-10-01 06:07 UTC