Chapter 16

Using Loops and Arrays

IN THIS CHAPTER

check Using for loops to the max

check Storing many values in a single variable

check Working with groups of values

This chapter has ten illustrations. For these illustrations, the people at John Wiley & Sons, Inc. insist on the following numbering: Figure 16-1, Figure 16-2, Figure 16-3, Figure 16-4, Figure 16-5, Figure 16-6, Figure 16-7, Figure 16-8, Figure 16-9, and Figure 16-10. But I like a different kind of numbering. I’d like to number the illustrations figure[0], figure[1], figure[2], figure[3], figure[4], figure[5], figure[6], figure[7], figure[8], and figure[9]. In this chapter, you find out why.

Some Loops in Action

The Java Motel, with its ten comfortable rooms, sits in a quiet place off the main highway. Aside from a small, separate office, the motel is just one long row of ground-floor rooms. Each room is easily accessible from the spacious front parking lot.

Oddly enough, the motel’s rooms are numbered 0 through 9. I could say that the numbering is a fluke — something to do with the builder’s original design plan. But the truth is, starting with 0 makes the examples in this chapter easier to write.

You, as the Java Motel’s manager, store occupancy data in a file on your computer’s hard drive. The file has one entry for each room in the motel. For example, in Figure 16-1, Room 0 has one guest, Room 1 has four guests, Room 2 is empty, and so on.

image

FIGURE 16-1: Occupancy data for the Java Motel.

You want a report showing the number of guests in each room. Because you know how many rooms you have, this problem begs for a for loop. The code to solve this problem is in Listing 16-1, and a run of the code is shown in Figure 16-2.

image

FIGURE 16-2: Running the code in Listing 16-1.

LISTING 16-1 A Program to Generate an Occupancy Report

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import static java.lang.System.out;

class ShowOccupancy {

public static void main(String args[]) throws FileNotFoundException {
Scanner diskScanner = new Scanner(new File("occupancy"));

out.println("Room Guests");

for (int roomNum = 0; roomNum < 10; roomNum++) {
out.print(roomNum);
out.print(" ");
out.println(diskScanner.nextInt());
}

diskScanner.close();
}
}

Listing 16-1 uses a for loop — a loop of the kind described in Chapter 15. As the roomNum variable’s value marches from 0 to 9, the program displays one number after another from the occupancy file. To read more about getting numbers from a disk file like my occupancy file, see Chapter 13.

remember This example’s input file is named occupancy — not occupancy.txt. If you use Windows Notepad to make an occupancy file, you must use quotation marks in the Save As dialog box’s File Name field. That is, you must type “occupancy” (with quotation marks) in the File Name field. If you don’t surround the name with quotation marks, Notepad adds a default extension to the file’s name (turning occupancy into occupancy.txt). A similar issue applies to the Macintosh’s TextEdit program. By default, TextEdit adds the .rtf extension to each new file. To override the .rtf default for a particular file, select Format ⇒ Make Plain Text. Then, in the Save As dialog box, remove the check mark from the check box labeled If No Extension Is Provided, Use “.txt”. (To override the default for all newly created files, choose TextEdit ⇒ Preferences. Then, in the Format part of the Preferences dialog’s New Document tab, select Plain Text.)

Deciding on a loop’s limit at runtime

On occasion, you may want a more succinct report than the one in Figure 16-2. “Don’t give me a long list of rooms,” you say. “Just give me the number of guests in Room 3.” To get such a report, you need a slightly smarter program. The program is in Listing 16-2, with runs of the program shown in Figure 16-3.

image

FIGURE 16-3: A few 1-room reports.

LISTING 16-2 Report on One Room Only, Please

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import static java.lang.System.out;

public class ShowOneRoomOccupancy {

public static void main(String args[]) throws FileNotFoundException {
Scanner keyboard = new Scanner(System.in);
Scanner diskScanner = new Scanner(new File("occupancy"));
int whichRoom;

out.print("Which room? ");
whichRoom = keyboard.nextInt();

for (int roomNum = 0; roomNum < whichRoom; roomNum++) {
diskScanner.nextInt();
}

out.print("Room ");
out.print(whichRoom);
out.print(" has ");
out.print(diskScanner.nextInt());
out.println(" guest(s).");

keyboard.close();
diskScanner.close();
}
}

If Listing 16-2 has a moral, it’s that the number of for loop iterations can vary from one run to another. The loop in Listing 16-2 runs on and on as long as the counting variable roomNum is less than a room number specified by the user. When the roomNum is the same as the number specified by the user (that is, when roomNum is the same as whichRoom), the computer jumps out of the loop. Then the computer grabs one more int value from the occupancy file and displays that value on the screen.

As you stare at the runs in Figure 16-3, it’s important to remember the unusual numbering of rooms. Room 3 has two guests because Room 3 is the fourth room in the occupancy file of Figure 16-1. That’s because the motel’s rooms are numbered 0 through 9.

Using all kinds of conditions in a for loop

Look at the run in Figure 16-3 and notice the program’s awful behavior when the user mistakenly asks about a nonexistent room: The motel has no Room 10. If you ask for the number of guests in Room 10, the program tries to read more numbers than the occupancy file contains. This unfortunate attempt causes a NoSuchElementException.

Listing 16-3 fixes the end-of-file problem.

LISTING 16-3 A More Refined Version of the One-Room Code

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import static java.lang.System.out;

public class BetterShowOneRoom {

public static void main(String args[]) throws FileNotFoundException {
Scanner keyboard = new Scanner(System.in);
Scanner diskScanner = new Scanner(new File("occupancy"));
int whichRoom;

out.print("Which room? ");
whichRoom = keyboard.nextInt();

for (int roomNum=0; roomNum < whichRoom && diskScanner.hasNext(); roomNum++) {
diskScanner.nextInt();
}

if (diskScanner.hasNext()) {
out.print("Room ");
out.print(whichRoom);
out.print(" has ");
out.print(diskScanner.nextInt());
out.println(" guest(s).");
}

keyboard.close();
diskScanner.close();
}
}

The code in Listing 16-3 isn’t earth-shattering. To get this code, you take the code in Listing 16-2 and add a few tests for the end of the occupancy file. You perform the diskScanner.hasNext test before each call to nextInt. That way, if the call to nextInt is doomed to failure, you catch the potential failure before it happens. A few test runs of the code in Listing 16-3 are shown in Figure 16-4.

image

FIGURE 16-4: The bad room number 10 gets no response.

technicalstuff In Listing 16-3, I want to know whether the occupancy file contains any more data (any data that I haven’t read yet). So I call the Scanner class’s hasNext method. The hasNext method looks ahead to see whether I can read any kind of data — an int value, a double value, a word, a boolean, or whatever. That’s okay for this section’s example, but in some situations, you need to be pickier about your input data. For example, you may want to know whether you can call nextInt (as opposed to nextDouble or nextLine). Fortunately, Java has methods for your pickiest input needs. A method like if (diskScanner.hasNextInt()) tests to see whether you can read an int value from the disk file. Java also has methods like hasNextLine, hasNextDouble, and so on. For more information on the plain old hasNext method, see Chapter 14.

Listing 16-3 has a big, fat condition to keep the for loop going:

for (int roomNum=0; roomNum < whichRoom && diskScanner.hasNext(); roomNum++) {

Many for loop conditions are simple “less-than” tests, but there’s no rule saying that all for loop conditions have to be so simple. In fact, any expression can be a for loop’s condition, as long as the expression has value true or false. The condition in Listing 16-3 combines a “less than” with a call to the Scanner class’s hasNext method.

Reader, Meet Arrays; Arrays, Meet the Reader

A weary traveler steps up to the Java Motel’s front desk. “I’d like a room,” says the traveler. So the desk clerk runs a report like the one in Figure 16-2. Noticing the first vacant room in the list, the clerk suggests Room 2. “I’ll take it,” says the traveler.

It’s so hard to get good help these days. How many times have you told the clerk to fill the higher-numbered rooms first? The lower-numbered rooms are older, and they are badly in need of repair. For example, Room 3 has an indoor pool. (The pipes leak, so the carpet is soaking wet.) Room 2 has no heat (not in wintertime, anyway). Room 1 has serious electrical problems (for that room, you always get payment in advance). Besides, Room 8 is vacant, and you charge more for the higher-numbered rooms.

Here’s where a subtle change in presentation can make a big difference. You need a program that lists vacant rooms in reverse order. That way, Room 8 catches the clerk’s eye before Room 2 does.

Think about strategies for a program that displays data in reverse. With the input from Figure 16-1, the program’s output should look like the display shown in Figure 16-5.

image

FIGURE 16-5: A list of vacant rooms, with higher-numbered rooms shown first.

Here’s the first (bad) idea for a programming strategy:

Get the last value in the occupancy file.
If the value is 0, print the room number.

Get the next-to-last value in the occupancy file.
If the value is 0, print the room number.

… And so on.

With some fancy input/output programs, this strategy may be workable. But no matter what input/output program you use, jumping directly to the end or to the middle of a file is a big pain in the boot. It’s especially bad if you plan to jump repeatedly. So go back to the drawing board and think of something better.

Here’s an idea! Read all values in the occupancy file and store each value in a variable of its own. Then step through the variables in reverse order, displaying a room number when it’s appropriate to do so.

This idea works, but the code is so ugly that I refuse to dignify it by calling it a listing. No, this is just a “see the following code” kind of thing. So please, see the following ugly code:

/*
* Ugh! I can’t stand this ugly code!
*/
guestsIn0 = diskScanner.nextInt();
guestsIn1 = diskScanner.nextInt();
guestsIn2 = diskScanner.nextInt();
guestsIn3 = diskScanner.nextInt();
guestsIn4 = diskScanner.nextInt();
guestsIn5 = diskScanner.nextInt();
guestsIn6 = diskScanner.nextInt();
guestsIn7 = diskScanner.nextInt();
guestsIn8 = diskScanner.nextInt();
guestsIn9 = diskScanner.nextInt();

if (guestsIn9 == 0) {
System.out.println(9);
}
if (guestsIn8 == 0) {
System.out.println(8);
}
if (guestsIn7 == 0) {
System.out.println(7);
}
if (guestsIn6 == 0) {

// … And so on.

What you’re lacking is a uniform way of naming ten variables. That is, it would be nice to write

/*
* Nice idea, but this is not real Java code:
*/

//Read forwards
for (int roomNum = 0; roomNum < 10; roomNum++) {
guestsInroomNum = diskScanner.nextInt();
}

//Write backwards
for (int roomNum = 9; roomNum >= 0; roomNum--) {
if (guestsInroomNum == 0) {
System.out.println(roomNum);
}
}

Well, you can write loops of this kind. All you need are some square brackets. When you add square brackets to the idea shown in the preceding code, you get what’s called an array. An array is a row of values, like the row of rooms in a one-floor motel. To picture the array, just picture the Java Motel:

  • First, picture the rooms, lined up next to one another.
  • Next, picture the same rooms with their front walls missing. Inside each room, you can see a certain number of guests.
  • If you can, forget that the two guests in Room 9 are putting piles of bills into a big briefcase. Ignore the fact that the guest in Room 5 hasn’t moved away from the TV set in a day-and-a-half. Instead of all these details, just see numbers. In each room, see a number representing the count of guests in that room. (If freeform visualization isn’t your strong point, take a look at Figure 16-6.)
image

FIGURE 16-6: An abstract snapshot of rooms in the Java Motel.

In the lingo of Java programming, the entire row of rooms is called an array. Each room in the array is called a component of the array (also known as an array element). Each component has two numbers associated with it:

  • Index: In the case of the Java Motel array, the index is the room number (a number from 0 to 9).
  • Value: In the Java Motel array, the value is the number of guests in a given room (a number stored in a component of the array).

Using an array saves you from having to declare ten separate variables: guestsIn0, guestsIn1, guestsIn2, and so on. To declare an array with ten values in it, you can write two fairly short lines of code:

int guestsIn[];
guestsIn = new int[10];

You can even squish these two lines into one longer line:

int guestsIn[] = new int[10];

In either of these code snippets, notice the use of the number 10. This number tells the computer to make the guestsIn array have ten components. Each component of the array has a name of its own. The starting component is named guestsIn[0], the next is named guestsIn[1], and so on. The last of the ten components is named guestsIn[9].

remember In creating an array, you always specify the number of components. The array’s indices always start with 0 and end with the number that’s one fewer than the total number of components. For example, if your array has ten components (and you declare the array with new int[10]), the array’s indices go from 0 to 9.

tip When you create an array variable, you can put square brackets after either the type name or the variable name. In other words, you can write

int guestsIn[];

as I do in this section, or you can write

int[] guestsIn;

as some programmers do. Either way, you’re defining exactly the same array variable. In the same way, you see

public static void main(String args[])

and you also see

public static void main(String[] args)

These two method headers have precisely the same meaning.

Storing values in an array

After you’ve created an array, you can put values into the array’s components. For example, the guests in Room 6 are fed up with all those mint candies that you put on people’s beds. So they check out, and Room 6 becomes vacant. You should put the value 0 into the 6 component. You can do it with this assignment statement:

guestsIn[6] = 0;

On one weekday, business is awful. No one’s staying at the motel. But then you get a lucky break: A big bus pulls up to the motel. The side of the bus sports a Loners’ Convention sign. Out of the bus come 25 people, each walking to the motel’s small office, none paying attention to the others who were on the bus. Each person wants a private room. Only 10 of them can stay at the Java Motel, but that’s okay, because you can send the other 15 loners down the road to the old C-Side Resort and Motor Lodge.

Anyway, to register ten of the loners at the Java Motel, you put one guest in each of your ten rooms. Having created an array, you can take advantage of the array’s indexing and write a for loop, like this:

for (int roomNum = 0; roomNum < 10; roomNum++) {
guestsIn[roomNum] = 1;
}

This loop takes the place of ten assignment statements because the computer executes the statement guestsIn[roomNum] = 1 ten times. The first time around, the value of roomNum is 0, so in effect, the computer executes

guestsIn[0] = 1;

In the next loop iteration, the value of roomNum is 1, so the computer executes the equivalent of the following statement:

guestsIn[1] = 1;

During the next iteration, the computer behaves as though it’s executing

guestsIn[2] = 1;

And so on. When roomNum gets to be 9, the computer executes the equivalent of the following statement:

guestsIn[9] = 1;

Notice that the loop’s counter goes from 0 to 9. Compare this with Figure 16-6 and remember that the indices of an array go from 0 to one fewer than the number of components in the array. Looping with room numbers from 0 to 9 covers all rooms in the Java Motel.

remember When you work with an array, and you step through the array’s components using a for loop, you normally start the loop’s counter variable at 0. To form the condition that tests for another iteration, you often write an expression like roomNum < arraySize, where arraySize is the number of components in the array.

Creating a report

The code to create the report in Figure 16-5 is shown in Listing 16-4. This new program uses the idea in the world’s ugliest code (the code from several pages back, with variables guestsIn0, guestsIn1, and so on). But instead of having ten separate variables, Listing 16-4 uses an array.

LISTING 16-4 Traveling through Data Both Forward and Backward

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

class VacanciesInReverse {

public static void main(String args[]) throws FileNotFoundException {
Scanner diskScanner = new Scanner(new File("occupancy"));
int guestsIn[];
guestsIn = new int[10];

for (int roomNum = 0; roomNum < 10; roomNum++) {
guestsIn[roomNum] = diskScanner.nextInt();
}

for (int roomNum = 9; roomNum >= 0; roomNum--) {
if (guestsIn[roomNum] == 0) {
System.out.print("Room ");
System.out.print(roomNum);
System.out.println(" is vacant.");
}
}

diskScanner.close();
}
}

Notice the stuff in parentheses in the VacanciesInReverse program’s second for loop. It’s easy to get these things wrong. You’re aiming for a loop that checks Room 9, and then Room 8, and so on.

if (guestsIn[9] == 0) {
System.out.print(roomNum);
}
if (guestsIn[8] == 0) {
System.out.print(roomNum);
}
if (guestsIn[7] == 0) {
System.out.print(roomNum);
}

… And so on, until you get to …

if (guestsIn[0] == 0) {
System.out.print(roomNum);
}

Some observations about the code:

  • The loop’s counter must start at 9:

    for (int roomNum = 9; roomNum >= 0; roomNum--)

  • Each time through the loop, the counter goes down by one:

    for (int roomNum = 9; roomNum >= 0; roomNum--)

  • The loop keeps going as long as the counter is greater than or equal to 0:

    for (int roomNum = 9; roomNum >= 0; roomNum--)

Think through each of these three items, and you’ll write a perfect for loop.

Initializing an array

In Listing 16-4, you put values into the guestsIn array by repeatedly reading numbers from a disk file and storing the numbers, element by element, in the array. There’s an easier way to put values into an array. When you declare the array, you provide an array initialization. Here’s how you do it:

class VacanciesInReverse {

public static void main(String args[]) {

int guestsIn[] = {1, 4, 0, 2, 2, 1, 4, 3, 0, 2};

for (int roomNum = 9; roomNum >= 0; roomNum--) {
if (guestsIn[roomNum] == 0) {
System.out.print("Room ");
System.out.print(roomNum);
System.out.println(" is vacant.");
}
}
}
}

In this code, the bold initialization line tells Java to put 1 into guestsIn[0], 4 into guests[1], 0 into guestsIn[2], and so on. This alternative to the code in Listing 16-4 uses no disk files and only one loop.

I don’t use array initialization in this chapter’s hotel room examples because storing values in a file is a bit more realistic. But you can use array initialization in your programs.

warning The feature that I describe in this section is called an initialization because you can’t use it as part of an assignment. In other words, you can write

int guestsIn[] = {1, 4, 0, 2, 2, 1, 4, 3, 0, 2};

but you can’t write

// Don’t do this:
int guestsIn[];
guestsIn = {1, 4, 0, 2, 2, 1, 4, 3, 0, 2};

After the end of an array’s declaration, you can no longer use curly braces to put values into the array.

Working with Arrays

Earlier in this chapter, a busload of loners showed up at your motel. When they finally left, you were glad to get rid them, even if it meant having all your rooms empty for a while. But now another bus pulls into the parking lot. This bus has a Gregarian Club sign. Out of the bus come 50 people, each more gregarious than the next. Now everybody in your parking lot is clamoring to meet everyone else. While they meet and greet, they’re all frolicking toward the front desk, singing the club’s theme song. (Oh no! It’s the Gregarian chant!)

The first five Gregarians all want Room 7. It’s a tight squeeze, but you were never big on fire codes, anyway. Next comes a group of three with a yen for Room 0. (They’re computer programmers, and they think the room number is cute.) Then there’s a pack of four Gregarians who want Room 3. (The in-room pool sounds attractive to them.)

With all this traffic, you had better switch on your computer. You start a program that enables you to enter new occupancy data. The program has five parts:

  • Create an array and then put 0 in each of the array’s components.

    When the Loners’ Club members left, the motel was suddenly empty. (Heck, even before the Loners’ Club members left, the motel seemed empty.) To declare an array and fill the array with zeros, you execute code of the following kind:

    int guestsIn[];
    guestsIn = new int[10];

    for (int roomNum = 0; roomNum < 10; roomNum++) {
    guestsIn[roomNum] = 0;
    }

  • Get a room number and then get the number of guests who will be staying in that room.

    Reading numbers typed by the user is pretty humdrum stuff. Do a little prompting and a little nextInt calling, and you’re all set:

    out.print("Room number: ");
    whichRoom = keyboard.nextInt();
    out.print("How many guests? ");
    numGuests = keyboard.nextInt();

  • Use the room number and the number of guests to change a value in the array.

    Earlier in this chapter, to put one guest in Room 2, you executed

    guestsIn[2] = 1;

    So now you have two variables: numGuests and whichRoom. Maybe numGuests is 5 and whichRoom is 7. To put numGuests in whichRoom (that is, to put five guests in Room 7), you can execute

    guestsIn[whichRoom] = numGuests;

    That’s the crucial step in the design of your new program.

  • Ask the user whether the program should continue.

    Are there more guests to put in rooms? To find out, execute this code:

    out.print("Do another? ");
    } while (keyboard.findWithinHorizon(".",0).charAt(0) == ’Y’);

  • Display the number of guests in each room.

    No problem! You already did this. You can steal the code (almost verbatim) from Listing 16-1:

    out.println("Room Guests");
    for (int roomNum = 0; roomNum < 10; roomNum++) {
    out.print(roomNum);
    out.print(" ");
    out.println(guestsIn[roomNum]);
    }

  • The only difference between this latest code snippet and the stuff in Listing 16-1 is that this new code uses the guestsIn array. The first time through this loop, the code does

    out.println(guestsIn[0]);

    displaying the number of guests in Room 0. The next time through the loop, the code does

    out.println(guestsIn[1]);

    displaying the number of guests in Room 1. The last time through the loop, the code does

    out.println(guestsIn[9]);

    That’s perfect.

The complete program (with these five pieces put together) is in Listing 16-5. A run of the program is shown in Figure 16-7.

image

FIGURE 16-7: Running the code in Listing 16-5.

LISTING 16-5 Storing Occupancy Data in an Array

import java.util.Scanner;
import static java.lang.System.out;

class AddGuests {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int whichRoom, numGuests;
int guestsIn[];
guestsIn = new int[10];

for (int roomNum = 0; roomNum < 10; roomNum++) {
guestsIn[roomNum] = 0;
}

do {
out.print("Room number: ");
whichRoom = keyboard.nextInt();
out.print("How many guests? ");
numGuests = keyboard.nextInt();
guestsIn[whichRoom] = numGuests;

out.println();
out.print("Do another? ");
} while (keyboard.findWithinHorizon(".",0).charAt(0) == ’Y’);
out.println();

out.println("Room Guests");
for (int roomNum = 0; roomNum < 10; roomNum++) {
out.print(roomNum);
out.print(" ");
out.println(guestsIn[roomNum]);
}

keyboard.close();
}
}

Hey! The program in Listing 16-5 is pretty big! It may be the biggest program so far in this book. But big doesn’t necessarily mean difficult. If each piece of the program makes sense, you can create each piece on its own and then put all the pieces together. Voilà! The code is manageable.

Looping in Style

Chapter 15’s Listing 15-6 uses an enhanced for loop to step through a bunch of values. In that program, the values belong to an enum type. Well, this chapter also deals with a bunch of values — namely, the values in an array. So you’re probably not surprised if I show you an enhanced for loop that steps through an array’s values.

To see such a loop, start with the code in Listing 16-5. The last loop in that program looks something like this:

for (int roomNum = 0; roomNum < 10; roomNum++) {
out.println(guestsIn[roomNum]);
}

To turn this into an enhanced for loop, you make up a new variable name. (What about the name howMany? I like that name.) Whatever name you choose, the new variable ranges over the values in the guestsIn array.

for (int howMany : guestsIn) {
out.println(howMany);
}

This enhanced loop uses the same format as the loop in Chapter 15.

for (TypeName variableName : RangeOfValues) {
Statements
}

In Chapter 15, the RangeOfValues belongs to an enum type. But in this chapter’s example, the RangeOfValues belongs to an array.

Enhanced for loops are nice and concise. But don’t be too eager to use enhanced loops with arrays. This feature has some nasty limitations. For example, my new howMany loop doesn’t display room numbers. I avoid room numbers because the room numbers in my guestsIn array are the indices 0 through 9. Unfortunately, an enhanced loop doesn’t provide easy access to an array’s indices.

And here’s another unpleasant surprise. Start with the following loop from Listing 16-4:

for (int roomNum = 0; roomNum < 10; roomNum++) {
guestsIn[roomNum] = diskScanner.nextInt();
}

Turn this traditional for loop into an enhanced for loop, and you get the following misleading code:

for (int howMany : guestsIn) {
howMany = diskScanner.nextInt(); //Don’t do this
}

The new enhanced for loop doesn’t do what you want it to do. This loop reads values from an input file and then dumps these values into the garbage can. In the end, the array’s values remain unchanged.

It’s sad but true. To make full use of an array, you have to fall back on Java’s plain old for loop.

Deleting Several Files

A program in Chapter 15 deletes a file named importantData.txt. The code to delete the file looks like this:

new File("importantData.txt").delete();

In that code, the new File call refers to a single file. It’s very nice code, but it doesn’t tell you how to delete a bunch of files. How can you write code to deal with several files at once?

Fortunately, Java provides ways to deal with bunches of files. One way uses an array of File objects. Listing 16-6 contains a program that illustrates this idea.

LISTING 16-6 Deleting All .txt Files

import java.io.File;

class IHateTxtFiles {

public static void main(String args[]) {

File folder = new File(".");
for (File file : folder.listFiles()) {
if (file.getName().endsWith(".txt")) {
file.delete();
}
}
}
}

In many operating systems (including Windows, Mac OS, and Linux), a single dot stands for the current working directory: the place where a program starts looking for files. For a Java program running in Eclipse, this working directory is the project’s root directory. For example, imagine that the code in Listing 16-6 lives in an Eclipse project named 16-06. Then your hard drive contains a folder named 16-06, which in turn contains a folder named src; which in turn contains the IHateTxtFiles.java file. (See Figure 16-8.) The program’s working directory is the 16-06 directory. So, in Listing 16-6, the code

folder = new File(".")

makes folder refer to the directory named 16-06.

image

FIGURE 16-8: Your project is in a folder named 16-06.

technicalstuff If you finished reading the previous paragraph, I know what you’re thinking. “The project’s root directory, 16-06, is a folder, not a file. But the code in Listing 16-6 says folder = new File("."). Why doesn’t the code say folder = new Folder(".")? Well, I’m glad you asked. It turns out that most operating systems blur the differences between folders and files. For Java’s purposes, the document IHateTxtFiles.java is a file, the folder named src is also a kind of a file, and the folder named 16-06 is also a kind of a file.

In Java, every File object has a listFiles method, and when you call folder.listFiles(), you get an array. Each “value” stored in the array is one of the files in the folder. In Listing 16-6, the enhanced for loop has the same format as the loop in the previous section.

for (TypeName variableName : RangeOfValues) {
Statements
}

In Listing 16-6, the RangeOfValues is an array. The array contains all the files inside the 16-06 project directory. So the enhanced for loop takes each file inside the 16-06 directory and asks, “Does this file’s name end with .txt?”

if (file.getName().endsWith(".txt"))

If a particular file’s name ends with .txt, delete that file:

file.delete();

Figures 16-9 and 16-10 show some “before” and “after” pictures in Eclipse’s Package Explorer. Before running this section’s example, the 16-06 directory contains things named src, aFile.txt, save.me, and xFile.txt. After running this section’s example, the 16-06 directory still contains src and save.me but no longer contains aFile.txt or xFile.txt.

image

FIGURE 16-9: Your ugly project, before using our .txt file deletion product.

image

FIGURE 16-10: Your lovely project, after using our .txt file deletion product.

remember After running this section’s program, you might not see any changes in Eclipse’s Package Explorer. To verify that the project directory no longer contains .txt files, select the 16-06 branch in the Package Explorer. Then, on Eclipse’s main menu, choose File ⇒ Refresh.

technicalstuff Eclipse’s Package Explorer looks like it’s displaying all the files and folders on a part of your hard drive. But looks can be deceiving. Some of the Package Explorer’s branches represent neither files nor folders. (For example, in Figures 16-9 and 16-10, the JRE System Library branch represents a bunch of related files — files that may or may not all be in the same directory.) And some of your hard drive’s files and folders don’t appear in Eclipse’s Package Explorer. (In addition to things like src, which appears in Eclipse’s Package Explorer, a project’s folder typically contains files named .classpath and .project and folders named .settings and bin. These additional files and folders aren’t normally displayed in Eclipse’s Package Explorer.)

technicalstuff When you call folder.listFiles(), the resulting array doesn’t include any of the things in subdirectories of the folder directory. Just to make sure, I created dFile.txt inside the 16-06 project’s src directory, and then I ran this section’s example. After running the program, dFile.txt had not been deleted.

tryitout Would you like to flex some array muscles? If so, here are some things for you to try.

INITIALIZING AN ARRAY

This experiment comes in three parts:

  • Run the following program to find out how array initialization works:

    public class Main {

    public static void main(String[] args) {
    int[] myArray = { 9, 21, 35, 16, 21, 7 };
    System.out.println(myArray[0]);
    System.out.println(myArray[1]);
    System.out.println(myArray[5]);
    // System.out.println(myArray[6]);
    }
    }

  • What happens when you uncomment the last System.out.println call in the previous bullet’s program and then run the program? Why does this happen?
  • What happens when you try to replace one line of code with two lines in the first bullet’s program?

    int[] myArray;
    myArray = { 9, 21, 35, 16, 21, 7 };

    Does this explain why an array initialization isn’t called an array assignment?

PICK AN ELEMENT

Create a program containing the following array initialization:

int amounts[] = {19, 21, 16, 14, 99, 86, 31, 19, 0, 101};

In your program, ask the user to input a position number — a number from 0 to 9. Have your program respond by displaying the value in that position of the amounts array. For example, if the user inputs 0, the program displays 19. If the user inputs 1, the program displays 21. And so on.

DISPLAY THE ELEMENTS

Create a program containing the following array initialization:

int amounts[] = {19, 21, 16, 14, 99, 86, 31, 19, 0, 101};

Add code to display all indices and values in the array. The first three lines of output should look like this:

The 0 element’s value is 19.
The 1 element’s value is 21.
The 2 element’s value is 16.

DISPLAY SOME OF THE ELEMENTS

Create a program containing the following array initialization:

int amounts[] = {19, 21, 16, 14, 99, 86, 31, 19, 0, 101};

Add a loop that displays the values in even-numbered positions of the array. The program’s output is 19 16 99 31 0.

GENERATING SQUARES

I’ve created a program that uses a loop to generate an array of the first 50 perfect squares. Here’s my program, with some code missing:

public class Main {

public static void main(String[] args) {
int squares[] = ___________;

for (______________________) {
squares[i] = _____;
}

System.out.println(squares[0]);
System.out.println(squares[1]);
System.out.println(squares[2]);
System.out.println(squares[49]);
}
}

Fill in the missing code. When you run the program, the output looks like this:

0
1
4
2401

FIND ONE VACANCY

Someone shows up at the front desk asking for a room. The hotel clerk doesn’t need a list of all vacant rooms. All the clerk needs is the number of one vacant room. Any vacant room will do. Modify the code in Listing 16-4 so that it shows only one room number (the number of a room that’s currently vacant).

SELECT A ROOM

Modify the code in Listing 16-5 so that it doesn’t ask the user which room number to put guests in. The code automatically selects a room from the rooms that are currently vacant.

HOW MANY GUESTS?

Modify the code in Listing 16-4 or Listing 16-5 so that the program displays the total number of guests in the motel. (To do this, the code adds up the numbers of guests in each room.)

PARALLEL ARRAYS

Create a new Eclipse project and put the following code in the project’s main method:

char[] cipher = { ’s’, ’f’, ’k’, ’l’, ’d’, ’o’, ’h’, ’z’, ’m’, ’b’,
’t’, ’a’, ’n’, ’g’, ’u’, ’v’, ’i’, ’q’, ’x’, ’w’, ’y’, ’c’,
’j’, ’r’, ’p’, ’e’ };
char[] plain = { ’e’, ’q’, ’s’, ’f’, ’i’, ’n’, ’h’, ’u’, ’r’, ’k’,
’g’, ’z’, ’c’, ’y’, ’x’, ’l’, ’m’, ’d’, ’w’, ’a’, ’b’, ’t’,
’p’, ’j’, ’v’, ’o’ };

This code creates two arrays. In the first array, cipher[0] is ’s’, cipher[1] is ’f’, cipher[2] is ’k’, and so on. In the second array, plain[0] is ’e’, plain[1] is ’q’, plain[2] is ’s’, and so on.

Finish writing the main method so that when the user types a lowercase letter, the program looks for that letter in the cipher array and responds by displaying the corresponding letter in the plain array.

For example, if the user types the letter s, the program answers back with the letter e. (The program discovers that s is in the 0 position of the cipher array, so the program displays the letter in the 0 position of the plain array. And the letter in the 0 position of the plain array is e.)

Similarly, if the user types f, the program displays q because f is in the 1 position of the cipher array and q is in the 1 position of the plain array.

DECIPHERING CIPHERTEXT

Here’s a challenging task for all you ciphertext enthusiasts! Enclose in a loop the code that you wrote for the earlier “Parallel arrays” experiment. Have the user type a word, followed immediately by a blank space. When the user presses Enter, the program repeatedly does what the code in the parallel-arrays experiment did. The program looks up all the user’s letters in the cipher array and displays the corresponding plain array letters. For example, if the user types rwpw, the program responds by displaying the word java.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.18