Overview
In this tutorial, we will discuss a common, yet quite tricky part of working with strings: string comparison. We will also discuss more ways to access the underlying character data of a string.
Equality Testing
In Java, string equality testing is tricky and often trips up novice programmers or programmers familiar with C++. Let's demonstrate where the trouble arises by declaring two identical strings:
String hello1 = "hello"; String hello2 = "hello";
Now, the naive way to test for equality would be to write
if (hello1 == hello2) System.out.println("This doesn't execute!");
However, the if expression will always yield false! The reason is that in Java all Object variables (everything but int, char, long, byte, short, float, double, boolean) are pointers. So, even though hello1 and hello2 point to objects that hold the same data, they point to different addresses in memory and direct comparison just compares these addresses. The correct way to compare the strings would be
if ( hello1.equals(hello2) ) Sytem.out.println("Yay! This works");
Moral of the story: Never use the == operator to compare equality of non-primitive types!
It is easy to remember which types are primitive, since they are lowercase, as opposed to the uppercase Object types.
Lexicographic Ordering
Lexicographic ordering is just a fancy word for alphabetic ordering, which arises in many occasions. There are two types of lexicographic orderings - case sensitive and case insensitive. In a case sensitive ordering, capital letters come before lowercase, so the word "Zoom" would be come before the word "adrenaline". CAUTION: Case sensitive ordering is the default in Java! Let's see an example:
String[] wordsArray = {"bouquet", "zebras", "Sugar", "Maroon", "smiles"}; Arrays.sort(wordsArray); //The array now contains {"Maroon", "Sugar", "bouquet", "smiles", "zebras"}
Now, if we would like to sort the array with case-insensitive alphabetical ordering, we could do the following:
String[] wordsArray = {"bouquet", "zebras", "Sugar", "Maroon", "smiles"}; Arrays.sort(wordsArray, String.CASE_INSENSITIVE_ORDER); //The new order is {"bouquet", "Maroon", "smiles", "Sugar", "zebras"}
Being able to alphabetically sort arrays of Strings is handy, but what if we just want to compare two strings and see which one comes first lexicographically? Then we use the String.compareTo and String.compareToIgnoreCase functions. If we had already defined String variables word1 and word2, here is how the compareTo function works:
if (word1.compareTo(word2) < 0) //The above being true means word1 < word2, i.e. word1 comes first alphabetically else if (word1.compareTo(word2) > 0) //If the result is greater than 0, the second argument comes first alphabetically else if (word1.compareTo(word2) == 0) //If compareTo returns 0, then the two strings are identical
Of course, the above results are case-sensitive; if case does not matter we would use String.compareToIgnoreCase.
Accessing Characters
We have seen how to convert a string into an array of characters, but sometimes we would like to just access a single character at a specific location. In those cases, we use the String.charAt function, which returns the character found at a given index. For example,
String testVar = "wheat"; testVar.charAt(0); //This returns 'w' testVar.charAt(4); //This returns 't' testVar.charAt(5); //This throws an exception (why?)
Challenge
Program
Write a function that is given a string of words as input, for example "cat dog Cow sheep". Words are separated by spaces;
your function has to split the big string into all the words it contains and then find the one that comes first alphabetically
(without considering case), which would be "cat" in the example above.
Then, your function should perform a simple hash on that word as follows:
1. Initialize the hash value to 0
2. For every character in the word, multiply its ASCII value by 3 raised to the power of its position
in the string and add it to the hash.
For example, for "cat", the hash would be 'c' * 3^0 + 'a' * 3^1 + 't' * 3^2 = 99 + 97*3 + 116*9 = 1434
Hint #1: To get the ASCII value of a char, cast it to an int.
Hint #2: Remember what you learned in String tutorials 1 and 2!
Sample Inputs:
"Your dog made a MESS outside"
"hook Smell secret letter knife"
"Cole Sherer and George Vulov rock"
"What a piece of work is man!"
"All that glitters is not gold"
Sample Outputs:
97
4325
1327
97
1361
