comparing strings with compareTo

Thinking about using our OCA 8 book to study for the Java Foundations Junior Associate exam? It covers most of the topics. See what other topics you need to learn and where to read about that. One of those topics is comparing two Strings using compareTo(). Luckily there are only two things you need to know.

What does compareTo() return.

Scenario Result
The two Strings are equal 0
The first String sorts earlier alphabetically  a negative number
The first String sorts later alphabetically a positive number

Let’s look at some examples:

String first = "abc";
String second = "def";
System.out.println(first.equals(first));  // true
System.out.println(first.compareTo(first)); // 0

System.out.println(first.equals(second));  // false
System.out.println(first.compareTo(second)); // -3
System.out.println(second.compareTo(first)); // 3

Don’t worry. You don’t have to know the answer is -3. You just have to know that it is negative or positive or zero.

How is alphabetically defined?
For the exam, you need to know that numbers sort before letters and uppercase sorts before lowercase. What do you think the output of this code is?

public class PlayTest {

	public static void main(String[] args) {

		String nums = "123";
		String uppercase = "ABC";
		String lowercase = "abc";
		printComparison(nums, nums);
		printComparison(nums, uppercase);
		printComparison(nums, lowercase);
		System.out.println();
		printComparison(uppercase, nums);
		printComparison(uppercase, uppercase);
		printComparison(uppercase, lowercase);
		System.out.println();
		printComparison(lowercase, nums);
		printComparison(lowercase, uppercase);
		printComparison(lowercase, lowercase);
	}

	private static void printComparison(String one, String two) {
		int result = one.compareTo(two);
		if (result == 0) {
			System.out.println("0");
		} else if (result < 0) {
			System.out.println("negative");
		} else {
			System.out.println("positive");
		}
	}

The answer is:

0
negative
negative

positive
0
negative

positive
positive
0

Make sure you can fill this in by yourself. You should also know the space sorts before letters. For example, printComparison(“ABC”, “A C”); prints out a positive number.

Summary

There’s not much you have to memorize. The key facts are:

  • The method name is compareTo()
  • Numbers sort before capital letters which sort before lowercase letters
  • Spaces sort before letters

Practice Questions

Question 1

What does the following output? (Choose all that apply)

String first = "MOO";
String second = "moo";
System.out.println(first.compareTo(second));
System.out.println(first.equals(second));

A: A negative number

B: Zero

C: A positive number

D: true

E: false

F: none of the above

Question 2

What does the following output? (Choose all that apply)

String first = "moo";
String second = " moo";
System.out.println(first.compareTo(second));
System.out.println(first.equals(second));

A: A negative number

B: Zero

C: A positive number

D: true

E: false

F: none of the above

Question 3

What does the following output? (Choose all that apply)

String first = "MOO";
String second = "MOO";
System.out.println(first.compareTo(second));
System.out.println(first.equals(second));

A: A negative number

B: Zero

C: A positive number

D: true

E: false

F: none of the above

Question 4

What does the following output? (Choose all that apply)

String first = "moo";
String second = "MOO";
System.out.println(first.compare(second));
System.out.println(first.equals(second));

A: A negative number

B: Zero

C: A positive number

D: true

E: false

F: none of the above

Question 5

What does the following output? (Choose all that apply)

String first = "MOO";
String second = "1";
System.out.println(first.compareTo(second));
System.out.println(first.equals(second));

A: A negative number

B: Zero

C: A positive number

D: true

E: false

F: none of the above

The answers are posted here.

using iterators in java

Thinking about using our OCA 8 book to study for the Java Foundations Junior Associate exam? It covers most of the topics. See what other topics you need to learn and where to read about that. One of those topics is iterating through a list.

Since Java 5, the most common way to iterate though a list (if you don’t need the loop index) is:

List<String>  list = Arrays.asList("sheep", "deer", "rat");
for (String name : list) {
   System.out.println(name);
}

Before Java 5 came along, there was another way:

List list = Arrays.asList("sheep", "deer", "rat");
 Iterator it = list.iterator();
 while (it.hasNext()) {
   String name = (String) it.next();
   System.out.println(name);
 }

But we are told to use generics in new code which would give us:

List<String> list = Arrays.asList("sheep", "deer", "rat");
 Iterator<String> it = list.iterator();
 while (it.hasNext()) {
   String name = it.next();
   System.out.println(name);
 }

Why would you do this? Shrug. For reading old code I guess. But it is on the test so no time like the present to learn this idiom. See what is wrong here?

// DOES NOT COMPILE
 List<String> list = Arrays.asList("sheep", "deer", "rat");
 Iterator<String> it = list.iterator();
 while (it.next()) {
   String name = it.hasNext();
   System.out.println(name);
 }

This one reverses the order of hasNext/next. Remember that you have to check that the iterator has a next element before getting it. Now what do you think is the problem with this?

// BAD
 List<String> list = Arrays.asList("sheep", "deer", "rat");
 Iterator<String> it = list.iterator();
 System.out.println(it.next());

If the list is empty, this code throws an exception. Probably not what you had in mind. Instead, you should write:


 List<String> list = Arrays.asList("sheep", "deer", "rat");
 Iterator<String> it = list.iterator();
 if (it.hasNext()) System.out.println(it.next());

Summary

There’s not much you have to memorize. The key facts are:

  • Call hasNext() in an if statement or while loop
  • Call next() once you know there is a next element
  • If the Iterator doesn’t use generics, you must cast unless you want Object

Practice Questions

Question 1

Which correctly fill in the blanks?


 List<String> list = Arrays.asList("a", "b", "c");
 Iterator<String> it = list.iterator();
 while (it._____()) {
   String name = it.______();
   System.out.println(name);
 }

A: hasNext, next

B: next, hasNext

C: The code does not compile with either A or B

D: The code throws an exception after being completed with A or B

Question 2

Which correctly fill in the blanks?


 List<String> list = Arrays.asList("a", "b", "c");
 Iterator it = list.iterator();
 while (it._____()) {
   String name = it.______();
   System.out.println(name);
 }

A: hasNext, next

B: next, hasNext

C: The code does not compile with either A or B

D: The code throws an exception after being completed with A or B

Question 3

Which correctly fill in the blanks?


 List list = Arrays.asList("a", "b", "c");
 Iterator<String> it = list.iterator();
 while (it._____()) {
   String name = it.______();
   System.out.println(name);
 }

A: hasNext, next

B: next, hasNext

C: The code does not compile with either A or B

D: The code throws an exception after being completed with A or B

The answers are posted here.

Formatting Strings for the Java Foundations Junior Associate exam

Thinking about using our OCA 8 book to study for the Java Foundations Junior Associate exam? It covers most of the topics. See what other topics you need to learn and where to read about that. One of those topics is formatting a String using %s, %n and %d. Conveniently for you , I had written a draft of this material for our OCP book before finding out that topic is not on the OCP 8 exam. I asked our publisher if I could post the material online and they said yes. I’ve edited it down to cover the subset that is on the Java Foundations Junior Associate exam. While the style matches our book, keep in mind it has not gone through the normal editing process by our publisher.

Note that the exam only expects you to know %d (digit/integer), %s (string) and %n (new line). This post covers a bit about %f (decimal) for two reasons:

  1. To help you remember why %d is digit/integer and not a floating point number
  2. To see the power of printf!

Formatting Strings

Formatting a String is useful because they let us specify a lot of complex logic clearly and succinctly . Imagine you had to write code to print out exactly 3 decimal places and align the decimal places. That would be a lot of coding and logic. Or it could be done using formatting:

List&amp;lt;Double&amp;gt; values = Arrays.asList(123.456, -1.4, 2.0);

for (Double d : values)

System.out.printf("%7.3f%n", d);

Don’t worry if this seems like magic. In a nutshell, this uses a width of 7 with 3 decimal places followed by a new line. It outputs:

123.456
-1.400
2.000

You don’t have to be able to write code like this. It is just to show the power of formatting. Also, there are a lot more types and options in existence than you need to know for the exam. See the Formatter class in the Javadoc for the ones not on the exam. The following figure shows what is going on from a high level. Java is substituting the parameter into a part of the format string.c05f003Ok. From this point on, you do need to know the material for the exam.

The PrintStream class defines the methods format and printf. They do the exact same thing. Java wanted to name the method format. However, C++ has had this method called printf for decades. Java supports both names to make things easy for both C++ developers and new developers.

System.out and System.err are both PrintStream instances. Remember that System.out.println() can show up in questions on just about anything as can System.out.printf(). This means you won’t know specifically if you are being tested on printf or something else.

The signatures of these two methods are:

  • public PrintWriter format(String fmt, Object… args)
  • public PrintWriter printf(String fmt, Object… args)

Remember that the three dots mean varargs. You can pass as many arguments as you want here. Also, remember that format and printf are exactly the same so we will start to use them interchangeably.

The first parameter is a String with embedded format parameters. The remaining parameters are an ordered list of the parameters to be inserted:

int num = 3;

String s = "Three: ";

System.out.format("%s %d", s, num);

Java sees a format string of a String to be inserted, followed by a space and then followed by a number to be inserted. The output is:

Three: 3

There are a number of parts to a format string. You only need to know a simplified version which looks like:

%[arg_index$]conversion_char

Conversion Character

%d and %s are format conversion specifiers. These format specifiers indicate the type of the parameter. You are only required to know three of the format specifiers for the exam as listed in following table. You do have to memorize these. They are copied from C++ so some of the types might seem odd to you. We’ve tried to give a description that helps you remember it rather than the shortest one possible. If you are a C++ developer, you might know that %d actually stands for decimal rather than digit. This is harder to remember for a new developer because the whole point of %d is that there is not a decimal point.

Remember that %d is digit (integer) and not double.

Conversion Specifier Description
%d Specifies a number with digits and no decimal point. (also known as an integer number)
%n New line (line break)
%s Specifies a String

Argument Index

The remaining part of a format string is the argument index. This is the index number followed by a $.

Argument indexes start counting from 1 instead of 0.

These examples should be straightforward:

System.out.printf("%s, %s", "play", "time"); &amp;nbsp;&amp;nbsp;&amp;nbsp;// play, time

System.out.printf("%2$s, %1$s", "play", "time"); // time, play

System.out.printf("%2$s, %2$s", "play", "time"); // time, time

The first line can omit the argument index since we want to use them in the order provided. The second line shows how to reverse the arguments. The final line shows how to use the same argument multiple times.

The Formatter Class

The Formatter class is an interpreter for the format strings used in format/printf methods. The class is similar to the PrintWriter class except that Formatter defines only the format methods and not the printf methods. Since the Formatter class didn’t exist in C++, Java didn’t need to be compatible with it. You invoke format in the way you do PrintWriter: passing in a format specifier followed by a comma-separated list of arguments.

For example, the following statements create a Formatter object and format a string of primitive types. What do you think this outputs?

StringBuilder sb = new StringBuilder();

Formatter fmt = new Formatter(sb);

int x = 123;

fmt.format("x=%d", x);

System.out.println(sb.toString());

In this example, the Formatter writes its output to a StringBuilder object. The int x is formatted and the resulting StringBuilder looks like this:

x=123

As you can see, working with Formatter is similar to working with PrintWriter.

Summary

printf() and format() use a format string. You need to know the simplified format of: %[arg_index$]conversion_char. The arg_index is optional. However, it must be specified in the correct order if present. The components you need to know are:

  • arg_index is an index that starts counting with one
  • conversion_character includes:
    • %b for boolean
    • %d for digit/decimal/integer (no decimal point)
    • %n for new line
    • %s for strings

Practice Questions

Question 1

What is the result of the following code?

System.out.format("%2$d is bigger than %2$d", 10, 5);

A: 10 is bigger than 5
B: 5 is bigger than 10
C: 10 is bigger than 10
D: 5 is bigger than 5
E: The code does not compile
F: A runtime exception is thrown

Question 2

Which of the following are true about the format string passed to printf? (Choose all that apply)

A: The argument index is a 0 based index.
B: The argument index is a 1 based index.
C: double goes with %d
D: int goes with %d

Question 3

What is the output of this statement?

System.out.printf("%2$d %1$s", "entry", 123.456);

A: 123 entry
B: 123.456 entry
C: entry 123
D: entry 123.456
E: The code does not compile
F: A runtime exception is thrown

Question 4

What is the output of this statement?

System.out.format("$n, $s", 123.456);

A: %n %s
B: $n $s
C: %n, %s
D: $n, $s
E: None of the above
F: A runtime exception is thrown

Question 5

What is the output of this statement?

System.out.println("%d", 123);

A: 0
B: 123
C: %d
D: The code does not compile
E: A runtime exception is thrown

The answers are posted here.