Methods versus static methods

Java is an object-oriented language, which means that most useful work in the language gets done by invoking methods on objects. We have already seen an example of objects and methods in our use of Scanner objects to obtain input from the user:

Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int a = input.nextInt();

Two things are essential here: we have to create a Scanner object and store it in a variable (input), and we have to invoke a method (nextInt) on the object to read some input from the user.

The nextInt method we invoked in the example above is an example of the most common kind of method. In addition to ordinary methods, Java also offers static methods. These are methods that belong to particular class, but are not invoked on an object. Instead, these methods are invoked via a special syntax:

<class name>.<method name>()

For example, the Java class library contains a Math class that offers a number of static methods for standard mathematical functions. Here is an example:

double y = Math.sqrt(2); // y = square root of 2

Here is a listing of some of the static methods available in the Math class.

Note that all of the trig methods work with radians, not degrees.

Working with Strings

Strings in the Java language are also objects, but they are a little bit unusual in that they can be created from a literal value in much the same way that ints and doubles can, and they also support a single operator, the concatenation operator +.

Initializing some ints from literal values and then adding them looks like

int a = 2;
int b = 3;
int c = a + b;

Similarly, initializing Strings from string literals and then concatenating them looks like

String a = "Hello, ";
String b = "world!";
String c = a + b;

Since Strings are actually objects, they support a number of useful methods. For example, to compute the length of a String you can use the length() method:

String str = "Here is some text."
int numChars = str.length();

To check two strings for equality, use the equals() method:

Scanner input = new Scanner(System.in);
String response;
System.out.print("Enter yes to continue, no to quit: ");
response = input.next();
if(response.equals("yes")) {
  // Do some more stuff...
}

Because the equals() method requires exact equality, including case, you may find it more flexible and convenient to use the alternative equalsIgnoreCase() method:

if(response.equalsIgnoreCase("yes")) {
  // Do some more stuff...
}

Important warning To compare Strings you must use equals() or equalsIgnoreCase(). Using == instead will not work properly, even though the compiler may let you try to use it.

if(response == "yes") // Warning!!! Does not work!!!

Converting between Strings and numeric types

On occasion you will encounter the need to convert numeric types to or from text. Java offers a number of techniques to do this.

The most common way to convert a numeric type into text is to use text concatenation. Most commonly, this takes place when you want to print the value of numeric variable along with some explanatory text. Here is a typical example:

double y = Math.sin(1.5);
System.out.println("sin(1.5) = " + y);

Any time you concatenate a numeric variable with a String, the numeric variable will automatically be converted to text for you as part of the concatenation process.

A second method to convert a numeric type to text is to use the static String method valueOf():

int n = 100;
String textForm = String.valueOf(n);
double x = 12.5;
textForm = String.valueOf(x);

You will not need to convert String data to numeric types all that often, because in most cases where we need to work with numbers in a program we will rely on the Scanner class to read in numbers as numbers. Here is a typical example:

Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and a double: ");
int n = input.nextInt();
double x = input.nextDouble();

On rare occasions you will find yourself with some text that needs to be reinterpreted as a number. To convert Strings to numeric values we use static parsing methods found in either the Integer class or the Double class:

String example = "100";
int n = Integer.parseInt(example);
example = "12.5";
double x = Double.parseInt(example);

The Random class

Another Java class we will use from time to time in examples is the Random class. The purpose of this class is to generate random numbers. The Random class has a nextInt(bound) method that generates a random integer between 0 and bound - 1. Here is an example that shows how to generate a random integer between 1 and 100:

Random rnd = new Random(); // Create a Random object
int n = rnd.nextInt(100) + 1;
// rnd.nextInt(100) produces a random int between 0 and 99.
// n is now a random number between 1 and 100.

To use the Random class in a program, we need to include an import statement:

import java.util.Random;

Extended example: a card game

Next I am going to construct a program that plays a simplified version of the card game 21 - I have simplified the rules for 21 to make it easier to construct a program to play the game.

Here are the rules for this simplified game:

Here are some key ideas we will work with in this program:

To get us started, here is some code to deal a card at random and compute both a point value and a number for the card:

int card, points;
String name;
Random rnd = new Random();
// Deal the card at random
card = rnd.nextInt(13) + 1;
// Compute how many points the card is worth
if(card >= 10) {
  points = 10;
} else {
  points = card;
}
// Determine the name of the card
if (card == 1) {
  name = "Ace";
} else if (card == 11) {
  name = "Jack";
} else if (card == 12) {
  name = "Queen";
} else if (card == 13) {
  name = "King";
} else {
  name = String.valueOf(card);
}

Although the logic for handling a single card is fairly simple, we also have to take into account the fact that in the game we will have to work with up to six different cards: the dealer can get up to three cards, and the player can have up to three cards. Since we will have to work with up to six distinct cards, we may need up to 6*3 = 18 different variables to store information about all of the cards. We can reduce the total number of variables needed by noting that we don't need to know the point values of the individual cards: we just need to track the total number of points each player has at each point in the game. To do that, we will use just two variables

int playerPoints, dealerPoints;

Once we have dealt two cards to each player and computed the total points for each player, we can write some logic to determine whether play ends with the first round or continues to the second round:

if (dealerPoints > 17 && playerPoints > 17) {
  System.out.println("Both players bust. Game ends in a tie.");
} else if (dealerPoints > 17) {
  System.out.println("Dealer busts. You win.");
} else if (playerPoints > 17) {
  System.out.println("You have gone bust. You lose.");
} else {
  // Play proceeds to round two...
}

If we make it to round two, the first thing to do in the second round is to ask the player if they want a third card. The code to do that would look like this:

System.out.print("What do you want to do, hit or stay? ");
String playerChoice = input.next();
if (playerChoice.equalsIgnoreCase("hit")) {
  // Deal the player a third card
  // Add the points for the third card to the player's total
}

After the player makes their move, the dealer has to decide whether or not to take a third card. Here is the logic to do that:

if ((playerPoints <= 17) &&
    (dealerPoints < 14 || dealerPoints < playerPoints)) {
  // Dealer takes a third card
}

Finally, here is the logic to determine who wins or loses at the end of round two:

if (playerPoints > 17) {
  System.out.println("You have gone bust. You lose.");
} else if (dealerPoints > 17) {
  System.out.println("Dealer busts. You win.");
} else {
  System.out.println("Dealer has " + dealerPoints +
                " and you have " + playerPoints + ".");
  if (dealerPoints > playerPoints) {
    System.out.println("Dealer wins on points.");
  } else if (dealerPoints == playerPoints) {
    System.out.println("Game ties on points.");
  } else {
    System.out.println("You win on points.");
  }
}

Here now is a NetBeans project that implements the full game.

Project Folder