Java Basics

Table of Contents

1 Reading

You should read this handout on the notional machine I'll refer to throughout this course. It describes a simplified model of a computer system and its components that will be useful for us.

2 Why Java?

2.1 Pedagogy

  • as you progress through CS classes, one goal is to deepen your understand computers and computation
    • Python typically implemented in C and/or Java, these languages expose more detail about what the computer is doing
      • 201 → Java, focuses on how data can be efficiently structured at a high level
      • 208 → C, focuses on low-level details of how computer systems function
  • learning a second language
  • preparing you for future CS coursework
    • forces you to think a lot more about types
  • No programming language is perfect, and Java certainly has some weaknesses
    • There are going to be a lot of exceptions and things that don't follow the overall pattern
    • Variety of reasons for this
      • Language has evolved over time since the 1990s
      • Adding some complexity allows programmers to achieve better performance
      • Bad early decision must be kept to maintain compatibility

2.2 Real-World Relevance

  • among top 3 most-used programming languages (with JavaScript, Python, C)
    • Android
    • finance
    • web infrastructure (e.g., AWS)
    • some scientific software
  • as a compiled language, Java offers some advantages
    • compiler detects errors before they happen
    • compiler can optimize our code (compile once, run many times)

3 Java Basics

3.0.1 Types

How to declare and initialize variables in Java

  • Variables must be declared (and given a type) before they are used
  1. Primitive Types

    Six primitive data types:

    Name Type Range Default Value
    boolean Boolean true or false false
    char Character data Any character '\0' (zero)
    int Integer \(-2^{31} \;...\; 2^{31} - 1\) 0
    long Long integer \(-2^{63} \;...\; 2^{63} - 1\) 0
    float Real \(-3.4028\mathrm{e}{38}\; ... 3.4028\mathrm{e}{38}\) 0.0
    double Double precision real \(-1.7977\mathrm{e}{308}\; ... 1.7977\mathrm{e}{308}\) 0.0

    Operators for primitive data types (in decreasing order of precedence):

    Operator Meaning
    ++ Unary increment
    -- Unary decrement
    ! Logical not
    * / % Multiplication, division, remainder
    + - Addition, subtraction
    < <= => > Numeric comparison
    == != Primitive and reference equality test
    && Logical and
    || Logical or
    = Assignment

    Things to be aware of:

    • Unlike Python, / will perform integer division if both operands are integers (i.e., the decimal part of the result will be discarded)
    • Assignment (=) is the only one of these operators that can be used with non-primitive types (objects)
      • (== and != can also be used, but as we'll see they often won't have the behavior you want and should be avoided with objects)
    • char is actually an integer type, holding the integer value corresponding to the given character under the Unicode-16 standard
      jshell> 'a' + 'b'
      $1 ==> 195
      
  2. Strings
    • You might have noticed strings were not among the primitive types, only individual characters
    • This is because strings are represented as objects in Java, which are fundamentally different from the primitive types
    • Some key differences:
      • Object type names are capitalized (String)
      • Primitive variables store the value, but object variables are references
        • References store the memory address of the object
      • References vs primitives have many implications detailed here: ./primitive-vs-references.html
        • We'll look at the effect on comparing values for equality in a bit
    • Official API documentation

3.0.2 main, Input/Output, if

  • All code in Java exists inside a class
import edu.princeton.cs.algs4.StdIn;  // we must import objects from the algs4 to use them

class Calculator {  // pair of curly braces { } indicate the code inside the class

    public static void main(String[] args) {  // curly braces indicate the code inside the main method
        System.out.print("Input your expression: ");  // prints a message to "standard out" (the terminal) 

        // each call to read___() reads the next portion of input separated by spaces (called a "token")
        // readString() returns it as a string, other versions attempt to convert it to a specific primitive type
        double left = StdIn.readDouble();
        String operator = StdIn.readString();
        double right = StdIn.readDouble();

        // v               v    if statements require the condition be inside parentheses
        if (operator == "+") {  // curly braces also indicate code within an if or an else
            System.out.println(left + right);  // println is like print, but adds a new line at the end
        } else {
            // when a program gets into an invalid state or otherwise encounters an error
            // it should "throw" an appropriate exception with a helpful message
            throw new UnsupportedOperationException(operator + " not an implemented operator");
                                                         // ^^^ can use + to concatenate strings
        }
    }
}
  • Mysterious main method incantation
    • The main method is called when we run the Java program, so every program has to start there
    • By the end of Monday's class, we will know what public, static, and void mean
    • For now, we must submit to the Java compiler's inscrutable demands
  • This version of our calculator doesn't work! It claims that "+" is not implemented…
    • This is where using == with objects can bite us—it checks whether two references refer to exactly the same address in memory
    • What we want is to compare the content of the two strings
      • Use .equals() for this:
        if (operator.equals("+")) {
        

3.0.3 while loop, else if, and a bug

  • Let's upgrade our calculator to let the user do multiple computations and add multiplication to the supported operations
import edu.princeton.cs.algs4.StdIn;

class Calculator {

    public static void main(String[] args) {
        int count = 0;  // keep track of how many expressions we've done, add an indicator to the output

        System.out.print("Input your expression: ");
        // StdIn.isEmpty() returns true if there is no more input
        // so we want to loop while that's not true (hence the use of !)
        // On mac, we can signal "no more input" by typing ctrl-d, and on Windows by typing ctrl-z and hitting enter
        while (!StdIn.isEmpty()) {  // note that while uses parentheses and curly braces like if
            double left = StdIn.readDouble();
            String operator = StdIn.readString();
            double right = StdIn.readDouble();

            if (operator.equals("+")) {
                System.out.println("[" + count + "]  " + left + right);
            } else if (operator.equals("*")) {  // we can have any number of else ifs between if and else
                System.out.println("[" + count + "]  " + left * right);
            } else {
                throw new UnsupportedOperationException(operator + " not an implemented operator");
            }
            count++;
            // calling hasNext will cause the program to wait for input, 
            // so we need to print our prompt before that
            System.out.print("Input your expression: ");
        }
        System.out.println("Nice computing with you! :)");  // never hurts to be nice
    }
}
  • This version has a bug too!
Input your expression: 8 + 6
[0]  8.06.0
  • We can use + with a number and a String, and Java will convert the number to a string and concatenate them
  • In System.out.println("[" + count + "] " + left + right);, the additions are evaluated from left to right, so it adds a string and left, and adds the result and right, giving us a concatenated mess
  • We should use parentheses to make sure left + right happens first:
System.out.println("[" + count + "]  " + (left + right));

3.0.4 Arrays, Command-Line Arguments, for loop

class Mean {

    // args is an array of Strings, each a token entered on the command line 
    // as part of the command starting the program
    public static void main(String[] args) {
        if (args.length == 0) {  // use .length to get the number of elements in an array
            // the user did not provide the command-line arguments we expected
            // print out a helpful message and then exit
            System.out.println("usage: java Mean arg1 [arg2 ...]");
            System.exit(1);
        }

        int total = 0;
        int index = 0;
        while (index < args.length) {
            total += Integer.parseInt(args[index]);
            index++;  // equivalent to index += 1 (but with slightly fewer keystrokes!)
        }
        System.out.println("the mean is " + total / args.length);
    }
}
  • Arrays in Java are objects (like Strings), but have several special properties/quirks
    • Unlike all other data structures in Java, array length is a field, not a method
      • e.g., args.length to get the length of an array, s.length() to get the length of a String s
    • An array type is given by add square brackets to the type of data in the array (e.g., String[] for an array of Strings)
    • Arrays are fixed length and can only contain a single type of data
      • You can change array elements, but you can't add or remove them (unlike Python lists)
      • Can't mix numbers and strings in a single array (unlike Python lists)
    • Arrays are the only thing in Java that can be indexed with square brackets
      • They are zero-indexed
    • java.util.Arrays provides a lot of useful array-related functions
  • One problem with the program above:
    • It's only printing the integer part of the mean (should be 2.5)
      $ java Mean 1 2 3 4
      the mean is 2
      
    • This is because in Java division between two integers returns an integer
    • If either or both of the numbers are real numbers (float or double), the result will be a real number
    • Two solutions: declare total a double instead of an int, or cast one of the quantities in the division to a double:
      System.out.println("the mean is " + (double)total / args.length);
      
  • Finally, the while loop works fine here, but Java has two other kinds of loops that would be more appropriate
    • C-style for loop
      • Using syntax borrowed from the C programming language, you can stuff the initialization and updating of the loop variable into the loop statement:
        for (int index = 0; index < args.length; index++) {
            total += Integer.parseInt(args[index]);
        }
        
      • Use thing kind of loop in the same situations (e.g., looping over indexes) that you would this style of Python for loop:
        for index in range(len(args)):
            total += int(args[index])
        
    • The for-each loop
      • Modern Java supports a for loop that iterates over the elements in an array:
        for (String arg : args) {
            total += Integer.parseInt(arg);
        }
        
      • Use thing kind of loop in the same situations (e.g., looping over elements) that you would this style of Python for loop:
        for arg in args:
            total += int(arg)
        

4 Practice Problems1

I will include practice problems with each topic to provide you an opportunity to practice what you've learned and check your understanding. They are for your benefit, so use them (or don't) however works best for you. We may go over specific practice problem during lecture, and of course questions about them are always welcome.

  1. Which of the following choices is the correct syntax for declaring a real number variable named grade and initializing its value to 4.0?
    1. int grade: 4.0;
    2. grade = double 4.0;
    3. double grade = 4.0;
    4. grade = 4;
    5. 4.0 = grade;
  2. Which of the following is the correct syntax to declare an array of ten integers?
    1. int a[10] = new int[10];
    2. int[10] a = new int[10];
    3. []int a = [10]int;
    4. int a[10];
    5. int[] a = new int[10];
  3. Imagine you are writing a personal fitness program that stores the user’s age, gender, height (in feet or meters), and weight (to the nearest pound or kilogram). Declare variables with the appropriate names and types to hold this information.
  4. Imagine you are writing a program that stores a student’s year (Freshman, Sophomore, Junior, or Senior), the number of courses the student is taking, and his or her GPA on a 4.0 scale. Declare variables with the appropriate names and types to hold this information.
  5. The following program contains 9 mistakes! What are they? (The line numbers shown are not part of the code, just for reference)
     1: class Oops2 {
     2:     public static void main(String[] args) {
     3:         int x;
     4:         System.out.println("x is" x);
     5: 
     6:         int x = 15.2;   // set x to 15.2
     7:         System.out.println("x is now + x");
     8: 
     9:         int y;          // set y to 1 more than x
    10:         y = int x + 1;
    11:         System.out.println("x and y are " + x + and + y);
    12:     }
    13: }
    
  6. Complete the following code, replacing the FINISH ME parts with your own code:
    class Count2 {
        public static void main(String[] args) {
            for (int i = /* FINISH ME */) {
                System.out.println(/* FINISH ME */);
            }
        }
    }
    

    to produce the following output:

    2 times 1 = 2
    2 times 2 = 4
    2 times 3 = 6
    2 times 4 = 8
    
  7. What elements does the array nums contain after the following code is executed?
    int[] nums = {2, 18, 6, −4, 5, 1};  // initializes nums be an array of these six ints
    for (int i = 0; i < nums.length; i++) {
        nums[i] = nums[i] + (nums[i] / nums[0]);
    }
    
  8. Write Java code to print out all the square numbers between 1 and 100 as well as their sum

Footnotes:

1

Solutions:

  1. 3. double grade = 4.0;
  2. 5. int[] a = new int[10];
  3. int age;
    String gender;
    double height;
    int weight;
    
  4. String year;
    int numberOfCourses;
    double gpa;
    
  5. Mistakes in Oops2 main method:
    • line 4: There should be a + between is and x.
    • line 4: Variable x has not yet been given any value.
    • line 6: Variable x is being redeclared. The word int should be omitted.
    • line 6: Variable x is being given a value of the wrong type (double).
    • line 7: The + x should be outside the quotes.
    • line 10: The word int should be omitted.
    • line 11: The word and should be surrounded by quotes.
  6. class Count2 {
        public static void main(String[] args) {
            for (int i = 1; i <= 4; i++) {
                System.out.println("2 times " + i + " = " + (2 * i));
            }
        }
    }
    
  7. After the code is executed, the nums array contains the following element values:
    [3, 24, 8, -5, 6, 1]
    
  8. class PrintSquares {
        public static void main(String[] args) {
            int sum = 0;
            for(int i = 1; i <= 10; i++) {
                System.out.println(i * i);
                sum += i * i;
            }
            System.out.println(sum);
        }
    }