Java4Python Companion

Introduction

There are specific examples of translations from Python to Java in Java4Python, but since it is mostly translation, it is a lot denser than the Python text for total newbies: Rather than have a lot of little snippets testing one bit of syntax at a time, it is mostly larger examples with translation information.

I will supply some examples relating back to previous Python code. You may well want to play more with little bits of syntax, like you already did in Python, and which did help solidify your memory. Now since you have tested out little snippets in Python, you can make up your own little snippets translated into Java to test.

In Python one place to check little snippets was the Python shell. Thankfully, there is corresponding tool for Java called jshell. If you have installed Java 11, you call start jshell from a terminal or directly in Idea. The usages are different though:

You can start right off testing for the arithmetic operation differences from Python! I like the terminal version.

I also have a concise summary of much of this conversion to Java data in this course: javaNotes.html. It is a reference - way to dense as an introduction!

Read the books sections

Lets Look at a Java Program Notes

Note that the literal string "Hello, world" is enclosed in double quotes, not single quotes. That is required in Java. (You will later see that single quotes are reserved for the separate Java data type char.)

You can run the Hello program in the browser, of course.

They give instructions for invoking the compiler and executing on your computer, without the Idea environment. You can demo this by using the terminal (simplest is the one built into Idea):

  1. Start Idea on a folder where you can store Java files.
  2. Copy the Hello program into a new file Hello.java.
  3. Save the file.
  4. Open a terminal.
  5. Enter command: javac Hello.java
  6. Enter command: java Hello

It is a convention to name a source file with the same name as its class containing the main method: So Hello.java has class Hello with the main method the Java looks for to start execution.

Java Data Types Notes

Start on Data Types stopping in the Numeric section before the GUI example using Swing, that comes just before the Strings section. You can interleave the subsections and the notes on them The rest of the Data Types section is either very short of ridiculously complicated. Follow below instead, starting with note on the parts you read, and then independent sections after that.

Numeric Notes

Because the Java primitive types are stored in fixed-size spaces, as a Python float is, they have restrictions. In particular int is not of unlimited size. Java has a number of sizes. The most common integer types are int and the larger long.

char
A char is a single character, with literals in single quotes, like 'x'. In Java this is distinct from a String, even a String with one character, like “x”. Technically char is a small numeric type: It just prints as a character, but can be used in arithmetic expressions. (More later.) Coming from Python, errors confusing a char and a one-character String are common!

Because the Java primitive types are stored in fixed-size spaces, like a Python float is, they have restrictions. Limits are accessible in Java with wrapper class static values: Integer.MAX_VALUE, Integer.MIN_VALUE, Double.MAX_VALUE, .... Here is some of the data collected:

long
64 bits; range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
int
32 bits; range -2,147,483,648 to 2,147,483,647
double
64 bits; maximum magnitude: 1.7976931348623157(10308); about 15 digits of accuracy
float
32 bits; maximum magnitude: 3.402823(1038); about 7 digits of accuracy

Operators - not in Java4Python

Java does arithmetic in the temperature conversion program. More detailed discussion of operators is in order:

Just as some Java data types correspond closely Python, while others have less in common, the same is true of operators.

+ - *
Addition, subtraction, multiplication and negation correspond closely, except if the result does not fit in the range of the result type: then an overflow error occurs, silently in Java! This could be a huge and hard to debug problem in Java!
/

Java does not use // for any division. (Rather // starts a comment.) Instead / does double duty, based on the type of the operands. If at least one operand is a double, it behaves like Python /. If both are ints, it behaves like Python // - only when both operands have the same sign, but not when the real number result would be negative: Python returns the floor of the real division (greatest integer <= real result) while Java truncates toward 0.

In the Fahrenheit conversion program, note that the expression (fahr - 32) * 5.0/9.0 evaluates correctly, and would have the same result if written (fahr - 32) * 5/9. Evaluating from left to right starting with double variable fahr means every intermediate operation produces a double result. However, the expression (fahr - 32) * (5/9) would not be the same! The parentheses around 5/9 means this integer quotient is calculated separately. The int operands means it would be the same as Python 5//9, so it equals 0! In Java 5/9 is not anything like 5/9 in math!

+ with a string

See the use of the + operator to print the result in the temperature conversion program. In Java + concatenates strings like in Python, but the use is more general than in Python: Python requires both operands to be strings. Java requires only one of the operands to be a string, and the second will be implicitly converted to a string. For example if x is an int, the expression "Value: " + x is illegal in Python, but fine in Java. In Python we would have to make the type conversion explicit: "Value: " + str(x).

The + operator is important in printing, since System.out.println is allowed only one parameter, not a list of parameters like in Python. Hence the one parameter is often an expression. One way to make a larger expression is with +. Later we will also see that Java has a format method something like in Python.

%
The remainder operation % is the same in both languages if the sign of both operands is the same, but not with different signs. With integers d and n, d*(n//d) + n%d always equals n in Python, and d*(n/d) + n%d always equals n in Java, but since integer division works differently with different signs, so does %.
&& || !
Boolean operator and, or and not in Python correspond exactly to Java &&, || and ! if operands have Boolean values.
+= ++ --
Java also allows the modification operators like +=. Incrementing and decrementing by 1 have special operators ++ and --, as illustrated in the List section.
==
With primitive numeric data, == checks for mathematical equality, like in Python. However, when two objects are compared in Java using the == operator they are tested to see if they are exactly the same object, that is do the two objects occupy the same exact space in the computers memory (Python is operator). You will see later that you need to use an equals method with objects.

Play with these in jshell! Get used to the similarities and differences. Here are a few specific ideas:

  • Set two int values x and y. Choose them so x+y will not have the right mathematical value.

  • Set long variables s and t to the same values. See that s+t has the right numerical value.

  • Compare 3/2 and 3.0/2 in Java.

  • Have a Python program or console going too. Compare -5 % 2 in Python and Java.

  • Also compare Python 2*(-5//2) + -5 % 2 and Java 2*(-5/2) + -5 % 2

  • Check that the boolean operator behavior match Python. For instance variations on

    (3 > 5) || (1 < 9 )
    (3 > 5) && (1 < 9 )
    

Declaring Variables Notes

In the temperature conversion example above, lines 5—7 contain variable declarations. If we use double rather than Double in lines 5 and 6, then fahr and cel are going to refer directly to spaces that store the primitive double data. Here I follow the usual form, and use the smaller and more efficient primitive type double, not the object type Double. We will use object wrapper classes only in the few places where they are required.

The declarations means that if we were to try an assignment like fahr = "xyz" the compiler would generate an error because "xyz" is a string and fahr is supposed to be a double.

The variable in will reference a Scanner object, discussed more below.

For Python programmers the following error is likely to be even more common. Suppose we forgot the declaration for cel and instead left line 6 blank. What would happen when we type javac TempConv.java on the command line?

When you see the first kind of error, where the symbol is on the left side of the equals sign it usually means that you have not declared the variable. If you have ever tried to use a Python variable that you have not initialized the second error message will be familiar to you. The difference here is that we see the message before we ever try to test our program. More common error messages are discussed in the later section Common mistakes.

Data Review Questions

  1. Most of Java arithmetic is just like normal math. The exceptions are most important: What are they?

  2. What are the consequences of numerical value types each being stored in a fixed amount of memory space?

  3. What is the order of operations if several of the same level, are chained together like x + y + z? This can matter in Java (including in a question below).

  4. Which of these individual two-line fragments could fit into a legal Java program? Explain:

    w = 3;
    w = 4;
    
    x = 3;
    x = x+1;
    
    y = 3;
    y = "hello";
    
    z = 3.5
    z = 3;
    
    q = 3;
    q + 1 = q;
    
  5. For the legal pairs above, what could the type of the variable have been declared? You can check them in jshell, giving the declaration first.

Input / Output / Scanner Notes

In the creation of the Scanner object: Java is verbose when calling a constructor for an object type like Scanner. The constructor must be preceded by the keyword new, as in in = new Scanner(System.in); Like forgetting semicolons, omitting the new is a really common error for Python programmers. Try removing the new and run, and see what the error says -- so you are prepared!

I object to the book's use of the wrapper types like Double when discussing the Scanner class. The wrapper classes are even listed as return types in the book, like for nextDouble(): In fact all the basic numeric ones return primitive types like double.

Again, because primitives have less overhead, and Java generally wraps/unwraps implicitly as needed, use the primitive type where you can (most everywhere).

Note that the Scanner input methods significantly differ from Python input with types. Python conveniently includes the prompt parameter for the input function. In Java you need to have a separate preceding statement to print the prompt (or as we will see later, write our own utility methods that do both).

The table of Scanner methods ends with nextLine(). This is like Python input() (no prompt) IF you are at the start of input or last used nextLine() for the previous line. The difference is that in Python, you always read a whole line at a time, and pass the newline to be ready for the start of the next line, but the other Java Scanner input methods, like nextInt(), read to the end of a token ONLY,(even through several lines if there is only whitespace in between), but not necessarily to the end of a line, and always leaving any following newline unread. Calling nextLine() reads through the next '\n', which could just be the rest of a line after a token read with something like nextInt().

For example if the next part of the input for Scanner in is

and you have the code

int n = in.nextInt();  // ok, n is 42
String s =  in.nextLine();  oops, s is ""

You would need a middle line in.nextLine(); for s to be the long string. Easy to cause problems!

Java has both println and print methods. The latter does not automatically add a newline.

This can be simulated in Python:

print(s, end='')

is like System.out.print(s).

The methods hasNextInt, hasNextDouble can check to see if the next token after possible whitespace has the proper form to be seen as an int or double.

A Scanner can also be used to read from a file or just a string. Both are finite - with an end. In that context the all the hasNext... methods will make sense, including plain hasNext, meaning there is some kind of token still to come. This makes little sense in reading from the keyboard, where you could enter more data forever. If you use hasNext with the keyboard, your program would just stop and wait for more lines if you entered nothing but whitespace.

Please skip the final GUI example using the Swing class.

Division Exercise

Write a program Div.java with class Div

  • Prompts the user to enter an integer
  • Read it with a Scanner
  • Prompts the user to enter another integer, and then read it
  • Label and print the values of the integer quotient, remainder, and real quotient. For instance if the user enters 7 and then 2 you might print

Numeric Type Conversions

This section is not in Java4Python.

We had fewer numeric types in Python, so there were fewer conversion issues. We already saw in Python that 2.3 + 5 (float + int) made sense: the less general type int is converted implicitly to the more general type float. The same is true in Java.

In Python constructors could do explicit conversion, including where information is lost:

x = 2.8      # float
y = int(x)   # int 2
x = -5.7     # float
y = int(x)   # int -5

Converting a float to an int truncates toward 0 - losing the fractional part.

The exact same idea appears in Java with very different notation, called casting. A cast involves the new type name in parentheses before the value to be converted:

double x = 2.8;
int y = (int) x;
x = -5.7;
y = (int) x;

The resulting int values are truncations like in Python. An explicit cast is generally only needed when the new type holds less information. The other direction can be implicit:

double z = 2;

The Java char type can be trickier. It is a numeric type smaller than an int. Binary arithmetic operations with numeric types smaller than int get automatically converted to int operations. The character 'A' has numeric value (its ASCII code) 65. The following letters of the alphabet have successive numeric values.

char ch = 'A';
int v = ch; // 65
ch++;  // now ch is 'B'
v = ch; // 66
ch = (char)(c+1);  // 'C'  Note cast!!
int diff = ch - 'A' //2: 'C' 2 after 'A'
boolean isPast = ch > 'A'; // true

If the cast had been left out in the third to last line:

ch = ch + 1;

there would be an error, since ch + 1 is a char plus an int, where the char is implicitly converted to an int for the arithmetic, but then the larger type int cannot be assigned back to the smaller type char without an explicit cast.

The error in IntelliJ IDEA 2018 if the cast is omitted is:

java: incompatible types: possible lossy conversion from int to char

What if you want to round rather than truncate a double. There is a method Math.round, but it produces a double, This can be combined with casting to int:

double x = 2.8;
int r = (int)Math.round(x);  // r is 3, not 2: rounded not truncated.

We have been discussing casts with primitives. The same word, cast, and notation are used with objects with a totally different interpretation. It will only make sense after you study inheritance in your next class. We skip it here!

While Python has simple conversion syntax to change a string to a number, Java is more verbose:

int i = Integer.parseInt("-22");  // i is -22
double d = Double.parseDouble("-3.5");  // d is 3.5

The shortest notation to convert a number v, or anything else, to a String is "" + v using the conversion ability of + with a String.

Conversion and Op Questions

  1. What is printed?

    int x = 7, y = 2;
    double d = 5.678;
    char ch = 'H';
    ch--;
    System.out.println(x/y);
    System.out.println((int)d);
    System.out.println(ch);
    System.out.println('J' - ch);
    System.out.println('B' > ch);
    
  2. This is not obvious for many. What is printed? Explain.

    int x = 2, y = 3;
    System.out.println('Sum is ' + x + y);
    

    How would you fix it without further setting the value of a variable?

  3. Which of these casts is necessary, and which could be left out (and be legal and mean the same thing)? Before testing, think what the values of the variables will be:

    int x= (int)5.8;
    double y = (double)6;
    char c = (char)('a' + 1);
    int z = (int)'a' + 1;
    

String Notes

Unfortunately Java Strings do not allow indexing with square brackets. You need to use named methods instead. Here are some pretty direct conversions/comparisons.

Examples below use string/String variables called w and u:

Python Java Description
w[3] w.charAt(3) Return character at index 3
w[2:4] w.substring(2,4) Return substring from 2nd up to but not including 4th index
len(w) w.length() Return the length of the string
w.find('x') w.indexOf("x") Find the index of the first occurrence of x
w.split(',') w.split(",") Split the string at ',' into a list/array of strings
w.split() w.trim().split("\\s+") Split out non-whitespace strings
w + u same as Python Java: One of the operands does not have to be a string
w.strip() w.trim() Remove any whitespace at the beginning or end
w.replace("me", "I") same as Python Replace all occurrences of first parameter by second
s.upper() s.toUpper() Return string in uppercase
s.lower() s.toLower() Return string in lowercase

In Java the split method must have a parameter, and it is a regular expressions, or regex for short: another specialized language with variants embedded in many programming languages. To match the behavior of a Python string parameter, treated verbatim, you need to escape any of the following characters you use: []{}()+*^$?

The regex escape character is \, but unfortunately that is also the string escape character, so to get it to the regex, it, too, needs to be escaped. So if you wanted to split on +, you would need st.split("\\+").

Note the error: The first example for split in the book's String table is illegal. Here is a correction. It is tricky: Python w.split() (no Python parameter) ignores white space on either end of string w, and splits out tokens with any number of whitespace characters in between. Java will generate empty strings in the list if there is whitespace at the beginning, and you need a regex to handle multiple whitespace characters together, so to match Python you need the mouthful w.trim().split("\\s+").

Here is one more comparison, with a float/double x:

Python Java Description
'v: {:7.2f}\n'.format(x) String.format("v: %7.2f%n", x) Return a formatted string

In String.format the first parameter is used much like a Python format string to which you apply the format method. The % followed by modifiers is used much like the {} in Python format strings. The syntax after the % is a bit different than after a colon inside Python braces:

  • Java format modifiers end with a type designation: s prints anything as a string, d is for ints, and f is for doubles.
  • A field width can be given after the %.
  • You can show field width and precision for a double, like in Python. A number directly before the decimal point in a float/double format is the minimum field width for the formatted string, with extra blanks included on the left if the string would be too short. If the string is longer than the field-width, the field-width value is ignored.
  • The Java format component %n is special: It does not format the next parameter. While Java println adds an extra newline, there is no alternate to String.format that automatically inserts a newline.

The embedded formatting language is very large. Only some of the most common bits are illustrated above.

In general you should not use '\n' in Java: In Python, C#, and C++, '\n' is replaced in file output by whatever newline sequence is used by the current operating system. Not so in Java! (Windows and Unix/Mac use different newline conventions.) These days most applications are newline format agnostic, but not all. It may have changed recently, but the classic Windows Notepad does not know what to do with a plain '\n'.

The System.out.format method produces the same string as String.format but the string is directly printed to System.out, not returned. This is more important in Java, since System.out.println and System.out.print can only take a single argument, unlike the allowed parameter list in Python for print.

In jshell try some of the string method examples, trying various things, like I recommended for operators above.

String Op Review Questions

  1. What is printed by this fragment?

    String s = "question";
    System.out.println(s.length());
    System.out.println(s[2]);
    System.out.println(s.substring(2, 5));
    System.out.println(s.substring(3));
    System.out.println(s.indexOf("ti"));
    System.out.println(s.indexOf("to"));
    int j = s.indexOf("u"), k = s.indexOf("o");
    System.out.format("%s %s %s", j, k, s.substring(j, k));
    
  2. What is printed by this fragment?

    String s = "Word";
    s.toUpper();
    System.out.println(s);
    
  3. What is printed by this fragment?

    String a = "hi", b = a.toUpper();
    System.out.println(a+b);
    
  4. Are Strings mutable or immutable: which?

  5. Suppose we have a String s and want its length. Is this expression legal, or what should it be?

    s.length
    
  6. Which of these expressions are legal in Java? Think of the results. Explain.

    "a" + "b"
    "a" + 'b'
    "a" + 2
    2 + "a"
    "a" + 2 * 3;
    "a" + 2 + 3
    2 + 3 + "a"
    2 + 3 * "a"
    

    Think first; try in jshell; reconsider if necessary.

  7. Write a single println statement that would produce output on two separate lines, not just one.

List Notes

Java has various forms of lists. We will use the type ArrayList. Again there must be types for everything in Java, and a list can only contain elements of one type. That type is given in angle brackets, so an ArrayList of Strings called strList, initialized to an empty list would be declared verbosely as

ArrayList<String> strList = new ArrayList<String>();

Unfortunately you cannot use the nice [i] notation of Python to index Java lists. You need named methods. At least the names are reasonable.

While reading and writing to an element of a Python list use the same notation, like w[3], Java has distinct methods, get and set. Here is a comparison of Python and Java list manipulation.

List methods: Suppose w and w2 are lists of strings --

Python Java notes
value of w[3] w.get(3) Return/get value of item at index 3
w[3] = 'a' w.set(3, "a") Set item at index 3
w.append('a') w.add("a") Append item
len(w) w.size() Return the number of items in the list
w.find('x') w.indexOf("x") Find index of the first occurrence of x, or -1
w += w2 w.addAll(w2) add all of list w2, modifying w
'x' in w w.contains("x") membership test
not bool(w) w.isEmpty() (Python w is True if not empty)
w[:]=[] w.clear() Remove all items
w.pop(2) w.remove(2) remove and return item at index 2
w.sort() Collections.sort(w) sort according to natural ordering
w[2:4] w.subList(2, 4) sub-list that you can iterate over
', '.join(w) String.join(", ",w) creates string joined with ", " separators

If you want to iterate over w[2:4] and not change anything in the list, w.subList(2,4) is an analog, but it does not create a new list: it is a view of w. The analog of w2 = w[2:4], which copies item references to a new list, is the mouth-full w2 = new ArrayList<String>(w.subList(2,4)).

Compare the Python and Java for copying the upper case version of a list of strings to another list. Note the translation of the for-loop heading: the loop variable must be given a type in Java. First we show Python (a slow way, to be analogous to the Java way, since there are no list literals in Java):

fruit = list()
fruit.append("apple")
fruit.append("pear")
fruit.append("plum")

FRUIT = list()
for item in fruit:
   FRUIT.append(item.upper())

Now Java:

ArrayList<String> fruit = new ArrayList<String>();
fruit.add("apple");
fruit.add("pear");
fruit.add("plum");

ArrayList<String> FRUIT = new ArrayList<String>();
for (String item: fruit)
{
   FRUIT.append(item.toUpper());
}

Both versions end up with FRUIT containing, "APPLE", "PEAR", and "PLUM".

In general the for-loop heading for processing items in a sequence, like an ArrayList, is

for ( type itemname : sequence )

In Java, if the for-loop body is the contain more than one statement, you need to enclose them in braces to make one compound statement. It is generally good practice to use the braces in general for loop bodies. In java the indentation of the loop body statements is a convention for human readability, but is ignored by the compiler.

Always give the element type for an ArrayList in your declaration and creation of new objects! This is one of the few places you do need the wrapper type in place of a primitive type.

On the other hand, method parameters can take advantage of auto-boxing:

ArrayList<Integer> nums = new ArrayList<Integer>(); // not int
nums.add(7);  // int 7 auto-converts to an Integer object

We will see other kind of loops soon.

For more extensive use of Java ArrayLists, you will want to see its documentation, https://docs.oracle.com/javase/11/docs/api/java/util/ArrayList.html.

See also the java.util.Collections class.

Lists are related to another type in Java: arrays.

Array Notes

Arrays in Java have some of the features of Python lists, including indexing, but unlike lists, their number of elements is fixed at creation time, and is unchangeable after that. Arrays are a built-in syntax, simpler than for ArrayLists.

Here is a variation on the fruit snippets above, first Python:

fruit = ["apple", "pear", "plum"]
n = len(fruit)
FRUIT = [""]*n # so list has n elements
for i in range(n)
   FRUIT[i] = fruit[i].upper()

Now Java, all with arrays

String[] fruit = {"apple", "pear", "plum");

int n = fruit.length;
String[] FRUIT = new String[n];
for (int i = 0; i < n; i++)
{
   FRUIT[i] = fruit[i].toUpper();
}

This is a very direct translation, line by line. There are a number of things to elaborate on:

  • An array with elements of type T has type T[], so String[] is an array of strings.

  • Arrays can be initialized in the declaration statement, much like Python lists, except the initializer is in braces {...}. This sets the fixed length of the array.

  • Note the length field (not method) in place of the Python len function.

  • Array variables can also be set to a new array, using the new syntax, with the element type, and this time with the size of the array inside square brackets. The size can be an int expression,

    new elementType [ arraySizeExpression ]

  • Here we use the second kind of Java for-loop heading. this usage directly corresponding to the range in Python is very common. More variations come later.

  • Single element indexing is just like in Python lists!

Some more array features:

  • An array is a form of sequence, like a list, so it can be used as the sequence in the for-loop heading form with a sequence.
  • Like with all Java objects, when an array is created, its full state is set. This is clear with the braces notation, but not with new elementType[size]. There is a standard initialization for all types in a new object that are not explicitly given a value:
    • Numeric types become 0 (or 0.0)
    • This includes the char type: (char)0 is a generally useless character, not the same as '0'. A way to initialize a char array is using String method toCharArray()
    • A boolean value becomes false.
    • Object element type become null, sort of like Python None, but null can only be a value indicating lack of an object. It cannot be assigned to a primitive type.

Examples:

  • new boolean[5] sets all 5 elements to false.

  • new int[10] sets all 10 elements to 0.

  • new String[3] sets all 3 elements to null, not ``""``.

  • This prints all the capital letters, one per line:

    char[] letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    for (char ch: letters)
    {
        System.out.println(ch);
    }
    
  • This produces an error:

String[] strArray = new String[10];
System.out.println(strArray[0].toUpper());

Here strArray[0] is null. You cannot apply any method to null, including toUpper, as if null were an object.

length vs. size

Arrays have a length attribute -- accessed with no parentheses after it. The length of array a is a.length. This is unlike Strings! The length of String s is s.length() (with parentheses of a method). The length cannot be changed for either an array or string.

It is also easy to conflate syntax for list lengths. Lists sizes can be changed: A different method name is used for the (current) length of ArrayList al: al.size().

List and Array Questions

  1. Distinguish the cases when you would want to use a list instead of an array, or the other way around.
  2. What are comparable features between arrays and lists, but with different syntax?
  3. If you delete an element from the middle of a list, what happens to the spot where you removed the element?

Static Function Notes

Java manages the scope of local variables like in Python.

In Python, code and function definitions can exist outside of a class. In Java all code is in a class definition. The closest analog to a Python function is a static method in a class. (We will get to creating instance methods later.)

The required method main is an example, but you can define other static functions. Like all methods, a return type must be given, and the formal parameters names in the heading are preceded by a type designation.

For static functions, you also need the modifier static.

Within the same class, any static function can be called, just with its name and actual parameters.

If you want the function to be callable from outside the class, you also need the initial modifier public.

Here is a function to return a new array containing the squares of the numbers in a passed array:

Here is a Python function to return a new list containing the squares of the numbers in a passed list nums:

def squares(nums):
    int n = nums.length;
    sq = [0]*n
    for i in range(n):
        sq[i] = nums[i]*nums[i]
    return sq

Now for passed array nums in Java, and an array returned:

public static int[] squares(int[] nums)
{
    int n = nums.length;
    int[] sq = new int[n];
    for (int i = 0; i < n; i++) {
        sq[i] = nums[i]*nums[i];
    }
    return sq;
}
Overloading and signatures

In Python there can be only one function within any scope with a particular name. Python does allow some limited flexibility with optional parameters.

Java does allow multiple functions with the same name. Here are simple examples:

System.out.println(3);
System.out.println("Hello");
System.out.println();

Note that the last version has no parameter. (This version just advances to the next line).

Since Java as statically typed and the types and number of formal parameters appear in a function definition, in addition to the function name, Java uses all of these features to determine the method signature. It chooses the appropriate function to use based on the signature.

Signatures must be unique, but not function names.

public static void foo(double n)
{
     System.out.println(n);
}
public static void foo(int n)
{
     System.out.println(n*n);
}

Then see what these calls would print!

foo(3);     // prints 9 (3*3)
foo(3.5);   // prints 3.5

Java does more significant things with signatures combined with implicit type conversion: If the foo with int parameter were not defined, both the calls listed above would work, but foo(3) would now produce 3.0: Since in this case there is not a method with the exact signature, Java looks for what the parameter(s) could be converted to implicitly: An int can be implicitly converted to double so the double parameter version would be called. You are not in general recommended to have functions with such close signatures, but here we are illustrating how the compiler works!

Function Review Questions

  1. Write the function definition heading for a static function called Q1 which has two int parameters, x and y, and returns a double.

  2. The function above must have what kind of a statement in its body?

  3. Each of these lines has a call to the function above, Q1. Which are legal? Explain:

    double d = Q1(2, 5);
    
    int x = Q1(2, 5);
    
    double y = Q1(2) + 5.5;
    
    System.out.println(Q1("2", "5"));
    
    System.out.println(Q1(2.5, 5.5));
    
    Q1(10, 20);
    
  4. Suppose Q1 does nothing except produce the value to return, like most functions returning a double. Which line in the previous problem is legal, but has no effect?

  5. Write the function definition heading for a static function called Q4 which has one string parameter, s, and returns nothing.

  6. Which of these lines with a call to the function above, Q4, is legal? Explain:

    Q4("hi");
    
    string t = Q4("hi");
    
    System.out.println(Q4("hi"));
    
    Q4("hi" + "ho");
    
    Q4("hi", "ho");
    
    Q4(2);
    
  7. Can you have more than one function/method in the same class definition with the same name?

  8. What is a function/method signature? Can you have more than one function/method declared in the same class definition with the same signature?

  9. In each part, is this a legal program? If so, what is printed? If not, why not?

    Each version uses the same code, except for different versions of main. Here is the common code with the body of main omitted:

    class Local1
    {
       static int Q(int a)  // 1
       {                    // 2
          int x = 3;        // 3
          x = x + a;        // 4
          return x;         // 5
       }                    // 6
    
       public static void main(String[] args)
       {
          // see each version
       }
    }
    
    1. Insert:

      public static void main(String[] args)
      {
         Q(5);
         System.out.println(x);
      }
      
    2. Insert instead:

      public static void main(String[] args)
      {
         int x= 1;
         Q(5);
         System.out.println(x);
      }
      
    3. Insert instead:

      public static void main(String[] args)  // 7
      {                                       // 8
         int x = 1, y = 2;                    // 9
         y = Q(5);                            // 10
         System.out.println(x + " " + y);     // 11
      }                                       // 12
      
  10. In the previous problem consider the common code with part c. Note the line numbers as comments.

    1. In what line(s) is Q being defined?
    2. In what line(s) is Q called?
    3. What is the return type of Q?
    4. What is a formal parameter to Q?
    5. What is used as an actual parameter to Q?
    6. What is the scope of the x in line 3?
    7. What is the scope of the x in line 9?

Dictionary Notes

Just as Python has the dict type, Java has an analog. Rather than the dictionary terminology, Java calls these objects Maps. The one corresponding to a Python dict is a HashMap.

A HashMap has both keys and values, so two types are specified to define a specific type: TreeMap<keyType, valueType>. This needs to occur both when the type is declared and later where the constructor is used, like we did with an ArrayList, only now specifying two types.

Like with lists, Java does not allow square bracket notation here. Named methods must be used. The main ones, get and set are like for lists, except a key is used as a parameter in place of an index number.

Comparisons for Dict/HashMap d:

Python Java
d = dict() d = new HashMap<keyType, valueType>()
d[key] = v d.set(key, v)
v = d[key] v = d.get(key) // if key present
v = d.get(key, None) v = d.get(key) // null if key not present
d.keys() d.getKeys()

Python's get can have any other value as second parameter, not just None, to be returned if the key is not in d. When a key is missing in Java's get, the replacement for an actual value is always null.

Java does not have Python's nice dictionary literal notation.

Conditionals

Read the book section Conditionals. The last parts on switch and Boolean Operators are optional. Continue with my further notes:

Java conditional are very much like Python. However in your zeal to put in Java syntax, you might unconsciously end a Java if-statement heading with a semicolon, like the required end of an assignment statement. This is deadly! Be very careful not to end the line of an if or while heading with a semicolon! like

if (x < 2);   // WRONG !!!
{
   System.out.println("Always printed, even if x is 1!")
}

After the close parenthesis a Java if statement expects one statement (simple or compound), and ; alone is technically a statement (an empty one, like Python pass)! And remember Java is not line oriented like Python. That means the statement in braces is the second statement after the if test - not a part of the if statement at all!

This causes lots of errors for Python programmers, generally forgetting semicolons, and madly trying to add them to make up for it.

A switch statement is error prone. (Omitting a break; is legal but generally wrong.) You may see them. You are not required to write them and I will not use them.

No chaining of comparisons: Though 1 < x < 5 is a legal boolean expression in Python, such chaining of comparisons is not legal in Java: You are stuck with 1 < x && x < 5.

Boolean Operators

You may skip this! Java does have the ugly expression syntax:

condition ? trueValue : falseValue

Python recently added a corresponding construction (much more like English!):

trueValue if condition else falseValue

You are not responsible for either (though the Python version is rather nice).

Conditional Review Questions

  1. Which of these are boolean expressions? Assume the variables are of type int:

    true
    True
    "false"
    x = 3
    n < 10
    count == 22
    x <= 2 || x > 10
    x == 2 || 3
    1 < y < 10
    
  2. What are the values of these expressions? Be able to explain:

    2 < 3 && 4 < 5
    2 < 3 && 4 < 3
    2 < 3 || 4 < 5
    2 < 3 || 4 < 3
    3 < 2 || 4 < 3
    2 < 3 || 4 < 5 && 4 < 3
    
  3. Correct the last two entries in the first problem, supposing the user meant "x could be either 2 or 3" and then "y is strictly between 1 and 10".

  4. Add parentheses in 2 < 3 || 4 < 5 && 4 < 3 to get a different result.

  5. Suppose you have four possible distinct situations in your algorithm, each requiring a totally different response in your code, and exactly one of the situations is sure to occur. Have many times must you have if followed by a condition?

  6. Suppose you have four possible distinct situations in your algorithm, each requiring a totally different response in your code, and at most one of the situations will occur, so possibly nothing will happen that needs a response at all. Have many times must you have if followed by a condition?

  7. Assume IsBig(x) returns a Boolean value. Remove the redundant part of this statement:

    if (IsBig(x) == true)
       x = 3;
    
  8. Write an equivalent (and much shorter!) statement with no if:

    if (x > 7)
       return true;
    else
       return false;
    
  9. Write an equivalent (and much shorter!) statement with no if:

    if (x > 7)
       isSmall = false;
    else
       isSmall = true;
    
  10. Assume x and y are local int variables. Code fragments are separated by a blank line below. Pairs of the fragments are logically equivalent, but not necessarily with a directly adjacent fragment. Match the pairs. Be sure you understand when different pairs would behave differently. Caution: there is some pretty awful code here, that we would hope you would never write, but you might need to correct/read! Think of pitfalls. In each equivalent pair, which code fragment is more professional?

    if (x > 7) {    //a
       x = 5;
    }
    y = 1;
    
    if (x > 7) {    //b
       x = 5;
       y = 1;
    }
    
    if (x > 7)      //c
       x = 5;
       y = 1;
    
    if (x > 7) {    //d
       x = 5;
    }
    else {
       y = 1;
    }
    
    if (x > 7)      //e
       x = 5;
    else if (x <= 7) {
       y = 1;
    }
    
    if (x > 7) {    //f
       y = 1;
    }
    if (x > 7) {
       x = 5;
    }
    
  11. Same situation as the last problem, and same caution, except this time assume the fragments appear in a function that returns an int. In each pair of equivalent fragments, which is your preference?

    y = 1;         //a
    if (x > 7) {
       return x;
    }
    
    if (x > 7) {   //b
       return x;
    }
    y = 1;
    
    if (x > 7) {   //c
       return x;
    }
    else {
       y = 1;
    }
    
    if (x > 7) {   //d
       return x;
       y = 1;
    }
    
    if (x > 7) {   //e
       y = 1;
       return x;
    }
    y = 1;
    
    if (x > 7) {   //f
       return x;
    }
    
    if (x > 7);    //g
       return x;
    
    return x;      //h
    
  12. Same situation as the last problem, and same caution:

    if (x > 5)        //a
       if (x > 7)
           return x;
    else
       y = 1;
    
    if (x > 5)  {     //b
       if (x > 7)
           return x;
    }
    else {
       y = 1;
    }
    
    if (x > 7)        //c
       return x;
    if (x <= 5)
       y = 1;
    
    if (x > 7)        //d
       return x;
    if (x > 5)
       y = 1;
    
  13. When reading a verbal description of a problem to solve, what are some words or phrases that suggest that some version of an if statement will be useful?

For-loops

I like what I write here rather than the section in the book.

Here is a more complete discussion of the second type of for-loop that we introduced:

As this form is most commonly used, it is equivalent to a Python for-loop with a range. As was discussed at the beginning of while-loops in Python, a for-loop with a range as sequence can be rewritten as a while loop:

for i in range(start, past):
    statements

# same as

i = start
while i < past:
   statements
   i += 1

There is a similar near-equivalence with a Java for-loop:

for(int i = 3; i < 17; i += 1) {
    statements
}

//  almost the same as

i = 3;
while (i < 17)
{
    statements
    i += 1
}

//or in general

for(initialization; test; update) {
    statements
}

//  almost the same as

initialization
while (test)
{
    statements
    update
}

Again, the most common use is like with range, but many other variations are possible, as long as the while syntax then make sense.

Here is an example with multiple variables in the initialization and update: reversing the order of a double array a:

for(int i = 0, j = a.length-1; i < j; i++, j--) {
    double temp = a[i]; // swap
    a[i] = a[j]
    a[j] = temp;
}

This uses two extended features:

Further special cases and caveats:

Here is an alternate use -- no range, printing all the powers of a previously given int b that are less than an int n:

for(int p = 1, p < n; p *= b) {
    System.out.print(p + ' ');
}
// if b is 3 and n is 50, it prints 1 3 9 27

Any such for-loop can always be replace by a while-loop. Why have this for-loop syntax at all?

First, although technically not required, there is a strong convention when using this form of for-loop: The statements in the body of the loop have no effect on the variables in the heading.

This convention means that you can just look at the for-loop heading and see the overall sequence that the loop variables in the heading go through. This means that like the other for-loop form, the sequence of loop variable values can be checked out without looking at the body of the loop at all.

The independence reduces the number of things that you need to consider at once. For instance you could look at the heading of a for-loop, and see, "oh, "I am going through all the array indices in order."

Also, it is easy to forget the update at the end of a while-loop -- causing an infinite loop. Concentrating all the loop variable progress in the heading may reduce the possibility of such an error.

Disadvantages of this for-loop pattern: To follow the code in execution order, you bounce back and forth between body and parts of the heading. And in many situations you may not be able to maintain the strong convention for for-loop variables. If you need more complicated interactions with values affecting the loop test, then a while-loop is the thing to use.

Notes on While Loops

It is worth following the latter part of the book's Loops and Iteration section, on while-loops (indefinite iteration).

One additional note: The do { ... } while (condition); loop is the one place in Java where there is a semicolon after a condition!

Loop and Array Exercises

  1. Write a static void method printNums with int array parameter that prints out all the elements of the parameter on one line, blank separated. Use it for tests of methods below.

  2. Write a program NoNegTest.java including a static void method called noNeg to mutate its int array parameter so all negative elements become 0. Include a test in main. For your tests remember the easy way to initialize an array with braces.

  3. Write a program AllUpperTest.java including a static method called allUpper with a String array parameter that does not modify the parameter array, but returns a String array with all the strings of the parameter array in upper case. (Use string method toUpper: "Hello".toUpper() returns "HELLO".) Include a test in main. Use a for-each loop to display the contents of the returned array.

  4. Write a program TestIncreasing.java including a static boolean method called isIncreasing with an int array parameter that returns true if the array elements are strictly increasing, and false otherwise. Include thorough tests in main. It is easy not to have diverse enough tests!

  5. Write a program TestIntFactorial.java the body of

    public static int factorial(int n)
    

    where factorial(n), or n! in math, means 1*2*...*n for positive n. By convention 0! is 1. 1! is 1; 2! is 1 * 2 = 2; 3! is 1*2*3 = 6.

    What is the largest value of n for which you get the correct answer in Java? (In Python there is no limit until you run out of system memory.) If you get a negative answer, it is clearly screwy, but overflow answers do not need to be negative. You might write some extra code to help with the test (not necessarily in your final program -- maybe just tested in jshell).

    After figuring out the answer to this question, in your main method do label and show the call to factorial with the largest int that works. Also label and show the result for the next int, with the wrong answer.

  6. Same as the last problem by with int type everywhere replaced by long, in program TestLongFactorial.java

Array Questions

  1. When do you want to use an array rather than just a bunch of individually named variables?

  2. While writing a program, must you know the exact size of an array that you are going to create?

  3. Before creating a new array in a program, must the program be able to calculate the proper size for the array?

  4. After you have created the array, can you change the size of the original array object?

  5. If I have the declaration

    int[] vals = new int[5];
    
    1. What is stored directly in the memory position for variable vals?
    2. Does vals[3] then have a clear value? If so, what?
    3. Can I later make variable vals refer to an array of a different size?
  6. Comment on the comparison between these two snippets:

    char[] a = {'n', 'o', 'w'};
    a[0] = 'c';
    
    String s = "now";
    s[0] = 'c';
    
  7. Is this legal?

    int[] a= {1, 2, 3, 4};
    //...
    a = new int[7];
    
  8. What is an alias? Why is understanding aliases important with arrays?

  9. If I have a function declared

    static void f(int num)
    //...
    

    and I call it from my main function

    int v = 7;
    f(v);
    System.out.println(v);
    

    Could f change the value of the variable v, so 1 is printed in main? If so, write a one-line body for f that does it.

  10. If I have a function declared

    static void f(int[] nums)
    //...
    

    and I call it from my main function

    int[] v = {7, 8, 9};
    f(v);
    System.out.println(v[0]);
    

    Could f change the value of the variable v[0], so 1 is printed in main? If so, write a one-line body for f that does it.

  11. What is printed by this snippet?

    int[] a = {1, 2, 3};
    int[] b = {4, 5, 6};
    b[0] = 7;
    a[1] = 8;
    b[2] = 9;
    System.out.println("" + a[0] + a[1] + a[2]);
    
  12. What is printed by this snippet? (Only the second line is changed.)

    int[] a = {1, 2, 3};
    int[] b = a;
    b[0] = 7;
    a[1] = 8;
    b[2] = 9;
    System.out.println("" + a[0] + a[1] + a[2]);
    
  1. After this line, what is the value of a[2]?

    boolean[] a = new boolean[5];
    
  2. This will cause a runtime error. Why?

    String[] a = new String[5];
    for(String s: a) {
       System.out.println(s.length());
    }
    

File Notes

Java is a lot more verbose than Python to get to open and use a file.

Reading Files

In Python we can just use something like:

fName = 'SomeTextFile.txt'
inFile = open(fName, 'r')

and just start reading. We need a lot more in Java.

Here is a sort of analog:

First at the top of the file:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

so we do not need the full class names later.

Then inside the method where you want the file use:

String fName = "SomeTextFile.txt";
File inFile;

try {
    inFile = new File("SomeTextFile.txt");
}  catch ( IOException e) {
         System.out.println("Sorry but I was unable to open " + fNmame);
         System.exit(0); # terminates the program
}

Scanner in = new Scanner(inFile);

and then you can read using the Scanner which I named in, with the same syntax as for reading from the keyboard.

This code needs some discussion!

First we need a File object, which we create with the assignment to inFile.

This creates an association with a file in your file system, but little more.

This code sits in a try-catch block. If Java cannot find a file SomeTextFile.txt where it is looking in the file system, then an error is caused, of type IOException.

Some run-time errors can just happen, like division by 0, without special code, the program will abort unceremoniously.

Other types, like IOException need extra code of some sort. We will deal with just one approach: catching such an error.

The body of the try-catch block can have fairly arbitrary code. The intention is somehow repair the error situation, or at least abort gracefully. The code shown inside the braces of the try-catch block above does the latter: First print a warning of what happened, and then terminates the program.

You can treat the try-catch block in the example code above pretty much as boilerplate.

There is much more to Exceptions and try-catch blocks, just this is what we need now. More in the next course, Data Structures.

Then you can go on to read from the file using the next... methods of a Scanner. Since a file is finite, it can be read all the way to the end. In this context the hasNext method makes sense: It check if there is any further token in the file.

Writing Files

The familiar object used to print to the screen, System.out, is of type PrintWriter. This and many other classes you need to write are in the package java.io. Rather than import all the classes individually, you can import them all with:

import java.io.*;

Then if printFileName is a String variable containing the name you want your output file to have, here is the mouthful of boilerplate to create a PrintWriter named `` out`` that can write to the file:

PrintWriter out;

try {
    out = new PrintWriter(
             new BuferedWriter(
                new File(printFileName) ));
}  catch ( IOException e) {
         System.out.println(
            "Sorry but I was unable to create " + printFileName);
         System.exit(0); # terminates the program
}

Then you can use, the methods println, print and format with the PrintWriter named out, just like you have with System.out.

You may want to write to a file that is specified by the user, who could enter something by mistake. In this case, where the user may have entered a bad name for the file, you might not want the try-catch block to make you abort. Here is a loop variation to keep on until the output file is opened. The catch clause just prints a message, and the loop continues. Let us assume you already have Scanner in able to read from the keyboard:

PrintWriter out = null;
String printFileName;

while (out == null) {
    System.out.print("Enter output filename: ");
    printFileName = in.nextLine();

    try {
        out = new PrintWriter( // if exception, no assignment to out
                 new BuferedWriter(
                    new File(printFileName) ));
    }  catch ( IOException e) {
             System.out.println(
                "Sorry but I was unable to create " + printFileName);
    }
}

Similar to Python, when you are done writing to your file you must close it. With the examples above, that would be out.close();.

Random Class

Java, too, can produce pseudo-random numbers. The full class name is java.util.Random

You need a Random object:

random rand = new Random();

Then Python

random.randrange(n)

matches Java

rand.nextInt(n)  // random one of 0 1 2 ... n-1

There is also a nextDouble producing a double value v, 0 <= v < 1.

Defining Classes in Java

I am completely replacing this Java4Python section. My replacement is lengthy, and in a separate document, userdefinedjavaobjects.html.

Do finish up with the remaining Java4Python sections, starting with Naming Conventions.

Also look at my few added notes below for Common Mistakes and Java Documentation Online.

Common Mistakes Notes

The Forgetting a Semicolon example might be elaborated: The caret (^) clearly does not show a place where you need a semicolon. It is the first place the compiler realizes you omitted a semicolon! This error and missing closing parenthesis are among the common mistakes where you need to look back to the previous line.

Recall the extra semicolon error mentioned in the Conditionals notes.

Here is one additional error to note, match Wrong if with else:

In Python it is easy to find the if that goes with an else: look upward to find an if with the same indentation. In Java you are encouraged to indent much like Python, but it has no intrinsic meaning to the compiler!

If you do not consistently put the sub-statements for the true and false choices inside braces, you can run into problems from the fact that the else part of an if statement is optional. Even if you use braces consistently, you may well need to read code that does not place braces around single statements. If Java understood indentation as in the recommended formatting style (or as required in Python), the following would be OK:

if (x > 0)
   if (y > 0)
      System.out.println("positive x and y");
else
   System.out.println("x not positive, untested y");

Unfortunately placing the else under the first if is not enough to make them go together. (Remember the Java compiler ignores extra whitespace). The following is equivalent to the compiler, with the else apparently going with the second if:

if (x > 0)
   if (y > 0)
      System.out.println("positive x and y");
   else
      System.out.println("x not positive, untested y");

The compiler is consistent with the latter visual pattern: an else goes with the most recent if that could still take an else. Hence if x is 3 and y is -2, the else part is executed and the statement printed is incorrect: in this code the else clause is only executed when x is positive and y (is tested and) is not positive.

If you put braces everywhere to reinforce your indentation, as we suggest, or if you only add the following one set of braces around the complete inner if statement:

if (x > 0) {
   if (y > 0)
      System.out.println("positive x and y");
}
else
   System.out.println("x not positive, untested y");

then the braces enclosing the inner if statement make it impossible for the inner if to continue on to an optional else part. The else must go with the first if. Now when the else part is reached, the statement printed will be true: x is not positive, and the test of y was skipped.

Java Documentation Online Notes

The initial documentation links may still be bad. Instead: All Java class libraries are documented and available online. Here is the official resource: https://docs.oracle.com/javase/8/docs/api/index.html?overview-summary.html

If you know the package that a class is in, you can reach it through the package. If you do not know the package, you can go to the Index, click the link for the starting letter. Then you can do a browser search in the (huge) page. Class entries have the class name, a space and a dash. Searching for that combination may help.