1. Understanding String Data Problems

    Manipulating characters and strings provides some challenges for the beginning Java programmer. For example, consider the TryToCompareStrings application shown in Figure. The main() method declares a String named aName and assigns Carmen to it. The user is then prompted to enter a name. The application compares the two names using the equivalency operator (55) and displays one of two messages indicating whether the strings are equivalent
    import java.util.Scanner; public class TryToCompareStrings { public static void main(String[] args) { String aName = "Carmen"; String anotherName; Scanner input = new Scanner(System.in); System.out.print("Enter your name > "); anotherName = input.nextLine(); if(aName == anotherName) // Do not use == to compare Strings’ contents. System.out.println(aName + " equals " + anotherName); else System.out.println(aName + " does not equal " + anotherName); } }
    As an object, a String variable name is not a simple data type—it is a reference; that is, a variable that holds a memory address. Therefore, when you compare two String objects using the 55 operator, you are not comparing their values, but their computer memory locations. Programmers want to compare the contents of memory locations (the values stored there) more frequently than they want to compare the addresses of the locations. Fortunately, the creators of Java have provided several classes that you can use when working with text data; these classes provide you with many methods that make working with characters and strings easier: • Character—A class whose instances can hold a single character value and whose methods manipulate and inspect single-character data • String—A class for working with fixed-string data—that is, unchanging data composed of multiple characters • StringBuilder and StringBuffer—Classes for storing and manipulating changeable data composed of multiple characters
  2. Using Character Class Methods

    You learned in Chapter 2 that the char data type is used to hold any single character— for example, a letter, digit, or punctuation mark. Recall that char literals are surrounded by single quotation marks. Because char is a primitive data type, variables of type char are not references, so you can compare their values using relational operators such as == and >. In addition to the primitive data type char, Java offers a Character class. The Character class contains standard methods for testing the values of characters. Table describes many of the Character class methods. The methods that begin with is, such as isUpperCase(), return a Boolean value that can be used in comparison statements; the methods that begin with to, such as toUpperCase(), return a character that has been converted to the stated format.
    MethodDescription
    isUpperCase()Tests if character is uppercase
    toUpperCase()Returns the uppercase equivalent of the argument; no change is made if the argument is not a lowercase letter
    isLowerCase()Tests if character is lowercase
    toLowerCase()Returns the lowercase equivalent of the argument; no change is made if the argument is not an uppercase letter
    isDigit()Returns true if the argument is a digit (0–9) and false otherwise
    isLetter()Returns true if the argument is a letter and false otherwise
    isLetterOrDigit()Returns true if the argument is a letter or digit and false otherwise
    isWhitespace()Returns true if the argument is whitespace and false otherwise; this includes the space, tab, newline, carriage return, and form feed
    public class CharacterInfo { public static void main(String[] args) { char aChar = 'C'; System.out.println("The character is " + aChar); if(Character.isUpperCase(aChar)) System.out.println(aChar + " is uppercase"); else System.out.println(aChar + " is not uppercase"); if(Character.islowerCase(aChar)) System.out.println(aChar + " is lowercase"); else System.out.println(aChar + " is not lowercase"); aChar = Character.toLowerCase(aChar); System.out.println("After tolowerCase(), aChar is " + aChar); aChar = Character.toUpperCase(aChar); System.out.println("After toUpperCase(), aChar is " + aChar); if(Character.isletterOrDigit(aChar)) System.out.println(aChar + " is a letter or digit"); else System.out.println(aChar + " is neither a letter nor a digit"); if(Character.isWhitespace(aChar)) System.out.println(aChar + " is whitespace"); else System.out.println(aChar + " 1s not whitespace"); } }
  3. Declaring and Comparing String Objects
    When you declare a String object, the String itself—that is, the series of characters contained in the String—is distinct from the identifier you use to refer to it. You can create a String object by using the keyword new and the String constructor, just as you would create an object of any other type. For example, the following statement defines an object named aGreeting, declares it to be of type String, and assigns an initial value of Hello to the String: String aGreeting = new String("Hello"); The variable aGreeting stores a reference to a String object—it keeps track of where the String object is stored in memory. When you declare and initialize aGreeting, it links to the initializing String value. Because Strings are declared so routinely in programs, Java provides a shortcut, so you can declare a String containing Hello with the following statement that omits the keyword new and does not explicitly call the class constructor: String aGreeting = "Hello";
    Comparing String Values
    In Java, String is a class, and each created String is an object. A String variable name is a reference; that is, a String variable name refers to a location in memory, rather than to a particular value. The distinction is subtle, but when you declare a variable of a basic, primitive type, such as int x = 10;, the memory address where x is located holds the value 10. If you later assign a new value to x, the new value replaces the old one at the assigned memory address. For example, if you code x = 45;, then 45 replaces 10 at the address of x. By contrast, when you declare a String, such as String aGreeting = "Hello";, aGreeting does not hold the characters that make up Hello; instead it holds a memory address where the characters are stored. If you subsequently assign a new value to aGreeting, such as aGreeting = "Bonjour";, the address held by aGreeting is altered; now, aGreeting holds a new address where the characters Bonjour are stored. If you declare two String objects and initialize both to the same value, the value is stored only once in memory and the two object references hold the same memory address. Because the data that comprises the String is stored just once, memory is saved. Consider the following example in which the same value is assigned to two Strings (as opposed to getting one from user input). The reason for the output in the following example is misleading. When you write the following code, the output is Strings are the same. String firstString = "abc"; String secondString = "abc"; if(firstString == secondString) System.out.println("Strings are the same"); Fortunately, the String class provides you with a number of useful methods that compare Strings in the way you usually intend. The String class equals() method evaluates the contents of two String objects to determine if they are equivalent. The method returns true if the objects have identical contents, no matter how the contents were assigned.
    import java.util.Scanner; public class CompareStrings { public static void main(String[] args) { String aName = "Carmen"; String anotherName; Scanner input = new Scanner(System.in); System.out.print("Enter your name > "); anotherName = input.nextline(); if(aName.equals(anotherName)) // Using the equals() method System.out.println(aName + " equals " + anotherName); else System.out.println(aName + " does not equal " + anotherName); } }
    When the String class compareTo() method is used to compare two Strings, it provides additional information to the user in the form of an integer value. When you use compareTo() to compare two String objects, the method: • returns zero if the values of two Strings are exactly the same • returns a negative number if the calling object is “less than” the argument • returns a positive number if the calling object is “more than” the argument Strings are considered “less than” or “more than” each other based on their Unicode values; thus, a is less than b, and b is less than c. For example, if aName refers to Roger, then aName.compareTo("Robert"); returns a 5. The number is positive, indicating that Roger is more than Robert. This does not mean that Roger has more characters than Robert; it means that Roger is alphabetically “more” than Robert. The comparison proceeds as follows: • The R in Roger and the R in Robert are compared, and found to be equal. • The o in Roger and the o in Robert are compared, and found to be equal. • The g in Roger and the b in Robert are compared; they are different. The compareTo() method returns the value 5 because the numeric value of g minus the numeric value of b is 5 (because g is five letters after b in the alphabet). Often, you won’t care what the specific return value of compareTo() is; you simply want to determine if it is positive or negative. For example, you can use a test such as if(aWord.compareTo(anotherWord) < 0)… to determine whether aWord is alphabetically less than anotherWord. If aWord is a String variable that refers to the value hamster, and anotherWord is a String variable that refers to the value iguana, the comparison if(aWord.compareTo(anotherWord) < 0) yields true.
    Empty and null Strings
    Programmers often are confused by the difference between empty Strings and null Strings. You can create an empty String named word1 and two null Strings named word2 and word3 with the following statements: String word1 = ""; String word2 = null; String word3; The empty String word1 references a memory address where no characters are stored. The null String word2 uses the Java keyword null so that word2 does not yet hold a memory address. The unassigned String word3 is also a null String by default. A significant difference among these declarations is that word1 can be used with the String methods described in this chapter, but word2 and word3 cannot be. For example, assuming a String named someOtherString has been assigned a value, then the comparison word1. equals(someOtherString) is valid, but word2.equals(someOtherString) causes an error. Because Strings are set to null by default, some programmers think explicitly setting a String to null is redundant. Other programmers feel that explicitly using the keyword null makes your intentions clearer to those reading your program. You should use the style your organization recommends.
  4. Using a Variety of String Methods

    A wide variety of additional methods are available with the String class. The methods toUpperCase() and toLowerCase() convert any String to its uppercase or lowercase equivalent. For example, if you declare a String as String aWord = "something";, then the string something is created in memory and its address is assigned to aWord. The statement aWord = aWord.toUpperCase(); creates SOMETHING in memory and assigns its address to aWord. Because aWord now refers to SOMETHING, aWord = aWord.toLowerCase(); alters aWord to refer to something. The length() method is an accessor method that returns the length of a String. For example, the following statements result in the variable len that holds the value 5. String greeting = "Hello"; int len = greeting.length(); The indexOf() method determines whether a specific character occurs within a String. If it does, the method returns the position of the character; the first position of a String is zero. The return value is –1 if the character does not exist in the String. For example, in String myName = "Stacy";, the value of myName.indexOf('S') is 0, the value of myName.indexOf('a') is 2, and the value of myName.indexOf('q') is –1. The charAt() method requires an integer argument that indicates the position of the character that the method returns, starting with 0. For example, if myName is a String that refers to Stacy, the value of myName.charAt(0) is S and the value of myName.charAt(4) is y. An error occurs if you use an argument that is negative, or greater than or equal to the length of the calling String. Instead of using a constant argument with charAt(), frequently you will want to use a variable argument to examine every character in a loop. For example, to count the number of spaces in the String mySentence, you might write a loop such as the following: for(int x = 0; x < mySentence.length(); ++x) if(mySentence.charAt(x) == ' ') ++countOfSpaces; The charAt() method also is useful when you want a user to enter a single character from the keyboard. The nextLine() method with a Scanner object for console input and the JOptionPane.showInputDialog() method for GUI input both return Strings. For example, if input has been declared as a Scanner object, you can extract a character from the user’s keyboard input with a statement such as the following: char userLetter = input.NextLine().charAt(0); The endsWith() method and the startsWith() method each take a String argument and return true or false if a String object does or does not end or start with the specified argument. For example, if String myName = "Stacy";, then myName.startsWith("Sta") is true, and myName.endsWith("z") is false. These methods are case sensitive, so if String myName = "Stacy";, then myName.startsWith("sta") is false. The replace() method allows you to replace all occurrences of some character within a String. For example, suppose that you decide to replace spaces with dashes in a part number. If String partNum = "BK 761 23";, then String newPartNum = partNum.replace(' ', '-'); assigns "BK-761-23" to newPartNum. The statement newPartNum = partNum.replace('X', '-'); would assign "BK 761 23" to newPartNum without any changes because 'X' is not found in newPartNum. The replace() method is case sensitive, so if String partNum = "BK 761 23";, then String newPartNum = partNum.replace('k', 'w'); results in no change. Although not part of the String class, the toString() method is defined for other classes to convert their objects to strings. For example, the Integer class toString() method converts an integer to a String. After the following three statements, theString refers to "4"—a String of length 1: String theString; int someInt = 4; theString = Integer.toString(someInt); If you declare another String and a double as follows, then after the following statements, anotherString refers to “8.25”—a String of length 4: String anotherString; double someDouble = 8.25; anotherString = Double.toString(someDouble); You also can use concatenation to convert any primitive type (variable or constant) to a String using the + operator. For example, if you declare a variable as int myAge = 25;, the following statement results in aString that refers to My age is 25: String aString = "My age is " + myAge; Similarly, if you write the following that concatenates an empty string to a float, then anotherString refers to "12.34". String anotherString; float someFloat = 12.34f; anotherString = "" + someFloat;
    import javax.swing.*; public class Businessletter { public static void main(String[] args) { String name; String firstName = ""; String familyName = ""; int x; char c; name = JOptionPane.showInputDialog(null, "Please enter customer's first and last name"); x = O; while(x < name.length()) { if(name.charAt(x) == ' ') { firstName = name.substring (O, x); familyName = name.substring(x + 1, name.length()); x = name.length(); } ++x; } JOptionPane.showMessageDialog(null, "Dear " + firstName + ",\nI am so glad we are on a first name basis" + "\nbecause I would like the opportunity to" + "\ntalk to you about an affordable insurance" + "\nprotection plan for the entire " + familyName + "\nfamily. Call A-One Family Insurance today" + "\nat 1-800-555-9287."); } }
    Converting String Objects to Numbers
    If a String contains all numbers, as in “649”, you can convert it from a String to a number so you can use it for arithmetic, or use it like any other number. For example, suppose you ask a user to enter a salary in an input dialog box. When you accept input using showInputDialog(), the accepted value is always a String. An advantage to a dialog box accepting a String by default is that no error is generated if the user enters a nonnumeric value. However, to be able to use the entered value in arithmetic statements, you must convert the String to a number. To convert a String to an integer, you use the Integer class, which is part of java.lang and is imported automatically into programs you write. The Integer class is an example of a wrapper. A wrapper is a class or object that is “wrapped around” a simpler element; the Integer wrapper class contains a simple integer and useful methods to manipulate it. In Chapter 2, you were introduced to the parseInt() method, which is part of the Integer class; the method takes a String argument and returns its integer value. For example, the following statement stores the numeric value 649 in the variable anInt: int anInt = Integer.parseInt("649"); You then can use the integer value just as you would any other integer. You can tell that parseInt() is a static method because you use it with the class name and not with an object. It is also easy to convert a String object to a double value. You must use the Double class, which, like the Integer class, is a wrapper class and is imported into your programs automatically. The Double class parseDouble() method takes a String argument and returns its double value. For example, the following statement stores the numeric value 147.82 in the variable doubleValue. double doubleValue = Double.parseDouble("147.82");
  5. Learning About the StringBuilder and StringBuffer Classes

    In Java, the value of a String is fixed after the String is created; Strings are immutable, or unchangeable. When you write someString = "Hello"; and follow it with someString = "Goodbye";, you have neither changed the contents of computer memory at the address represented by someString nor eliminated the characters that comprise Hello. Instead, you have stored Goodbye at a new computer memory location and stored the new address in the someString variable. If you want to modify someString from Goodbye to Goodbye Everybody, you cannot add a space and Everybody to the someString that contains Goodbye. Instead, you must create an entirely new String, Goodbye Everybody, and assign it to the someString address. If you perform many such operations with Strings, you end up creating many different String objects in memory, which takes time and resources. To circumvent these limitations, you can use either the StringBuilder or StringBuffer class. You use one of these classes, which are alternatives to the String class, when you know a String will be modified repeatedly. Usually, you can use a StringBuilder or StringBuffer object anywhere you would use a String. Like the String class, these two classes are part of the java.lang package and are imported automatically into every program. The classes are identical except for the following: • StringBuilder is more efficient. • StringBuffer is thread safe. This means you should use it in applications that run multiple threads of execution, which are units of processing that are scheduled by an operating system and that can be used to create multiple paths of control during program execution. Because most programs you write (and all the programs you will write using this book) contain a single thread, usually you should use StringBuilder. The rest of this section discusses StringBuilder, but every statement is also true of StringBuffer. You can create a StringBuilder object that contains a String with a statement such as the following: StringBuilder message = new StringBuilder("Hello there"); When you use the nextLine() method with a Scanner object for console input or a JOptionPane.showInputDialog() method for GUI input, user input comes into your program as a String. If you want to work with the input as a StringBuilder object, you can convert the String using the StringBuilder constructor. For example, the following two statements get a user’s input using a Scanner object named keyboard and then store it in the StringBuilder name: String stringName = keyboard.nextLine(); StringBuilder name = new StringBuilder(stringName); Alternately, you can combine the two statements into one and avoid declaring the variable stringName, as in the following: StringBuilder name = new StringBuilder(keyboard.nextLine()); When you create a String, you have the option of omitting the keyword new, but when you initialize a StringBuilder object you must use the keyword new, the constructor name, and an initializing value between the constructor’s parentheses. You can create a null StringBuilder variable using a statement such as the following: StringBuilder uninitializedString = null; The variable does not refer to anything until you initialize it with a defined StringBuilder object. Generally, when you create a String object, sufficient memory is allocated to accommodate the number of Unicode characters in the string. A StringBuilder object, however, contains a memory block called a buffer, which might or might not contain a string. Even if it does contain a string, the string might not occupy the entire buffer. In other words, the length of a string can be different from the length of the buffer. The actual length of the buffer is the capacity of the StringBuilder object. You can change the length of a string in a StringBuilder object with the setLength() method. The length of a StringBuilder object equals the number of characters in the String contained in the StringBuilder. When you increase a StringBuilder object’s length to be longer than the String it holds, the extra characters contain ‘\u0000’. If you use the setLength() method to specify a length shorter than its String, the string is truncated. To find the capacity of a StringBuilder object, you use the capacity() method. The StringBuilderDemo application in Figure 7-12 demonstrates this method. The application creates a nameString object containing the seven characters Barbara. The capacity of the StringBuilder object is obtained and stored in an integer variable named nameStringCapacity and displayed.
    import javax.swing.JOptionPane; public class StringBuilderDemo { public static void main(String[] args) { StringBuilder nameString = new StringBuilder("Barbara"); int nameStringCapacity = nameString.capacity(); System.out.println("Capacity of nameString is " + nameStringCapacity); StringBuilder addressString = null; addressString = new StringBuilder("6311 Hickory Nut Grove Road") ; int addStringCapacity = addressString.capacity(); System.out.println("Capacity of addressString is " + addStringCapacity); nameString.setLength(20); System.out.println("The name is " + nameString + "end"); addressString.setLength(20); System.out.println("The address is " + addressString); } }
    The ability of StringBuilder objects to be modified can make using them more efficient than using Strings when you know string contents will change repeatedly. However, if your program makes relatively few changes to strings, or requires String comparisons, you should not use StringBuilder. For example, although the equals() method compares String object contents, when you use it with StringBuilder objects, it compares references. To compare the contents of two StringBuilder objects named obj1 and obj2, you must first convert them to Strings with an expression such as the following: obj1.toString().equals(obj2.toString()) The two most useful methods with StringBuilder objects are append() and insert(). The append() method lets you add characters to the end of a StringBuilder object. For example, the following two statements together declare phrase to hold Happy and alter the phrase to hold Happy birthday: StringBuilder phrase = new StringBuilder("Happy"); phrase.append(" birthday"); The insert() method lets you add characters at a specific location within a StringBuilder object. For example, if phrase refers to Happy birthday, then phrase.insert(6, "30th "); alters the StringBuilder to contain Happy 30th birthday. The first character in the StringBuilder object occupies position zero. To alter just one character in a StringBuilder object, you can use the setCharAt() method, which allows you to change a character at a specified position. This method requires two arguments: an integer position and a character. If phrase refers to Happy 30th birthday, then phrase.setCharAt(6,'4'); changes the value into a 40th birthday greeting. One way you can extract a character from a StringBuilder object is to use the charAt() method. The charAt() method accepts an argument that is the offset of the character position from the beginning of a String and returns the character at that position. The following statements assign the character ‘P’ to the variable letter: StringBuilder text = new StringBuilder("Java Programming"); char letter = text.charAt(5); If you try to use an index that is less than 0 or greater than the index of the last position in the StringBuilder object, you cause an error known as an exception and your program terminates. One version of the StringBuilder constructor allows you to assign a capacity to a StringBuilder object when you create it. For example: StringBuilder prettyBigString = new StringBuilder(300); When you can approximate the eventual size needed for a StringBuilder object, assigning sufficient capacity can improve program performance. For example, the program in Figure compares the time needed to append Java 200,000 times to two StringBuilder objects—one that has an initial capacity of 16 characters and another that has an initial capacity of 800,000 characters. Figure 7-15 shows a typical execution; the actual times will vary from execution to execution and will be different on different computers. However, extra time is always needed for the loop that appends to the initially shorter StringBuilder because new memory must be allocated for it repeatedly as the object grows in size.
    import java.time.*; public class ConcatenationTimeComparison { public static void main(String[] args) { long startTime, endTime; final int TIMES = 200_000; final int FACTOR = 1_000_000; int x; StringBuilder string1 = new StringBuilder(""); StringBuilder string2 = new StringBuilder(TIMES * 4); LocalDateTime now; now = LocalDateTime.now(); startTime = now.getNano(); for(x = 0; x < TIMES; ++x) string1.append("Java"); now = LocalDateTime.now(); endTime = now.getNano(); System.out.println("Time with empty StringBuilder: " + ((endTime - startTime) / FACTOR + " milliseconds")); now = LocalDateTime.now(); start Time = now.getNano(); for(x = O; x < TIMES; ++x) string2.append("Java") ; now = LocalDateTime.now(); endTime = now.getNano(); System.out.println("Time with empty StringBuilder: " + ((endTime - startTime) / FACTOR + " milliseconds")); } }
  6. You Do It Exercises

    public class CharacterInfo { public static void main(String[] args) { char aChar = 'C'; System.out.println("The character is " + aChar); if(Character.isUpperCase(aChar)) System.out.println(aChar + " is uppercase"); else System.out.println(aChar + " is not uppercase"); if(Character.isLowerCase(aChar)) System.out.println(aChar + " is lowercase"); else System.out.println(aChar + " is not lowercase"); aChar = Character.toLowerCase(aChar); System.out.println("After toLowerCase(), aChar is " + aChar); aChar = Character.toUpperCase(aChar); System.out.println("After toUpperCase(), aChar is " + aChar); if(Character.isLetterOrDigit(aChar)) System.out.println(aChar + " is a letter or digit"); else System.out.println(aChar + " is neither a letter nor a digit"); if(Character.isWhitespace(aChar)) System.out.println(aChar + " is whitespace"); else System.out.println(aChar + " is not whitespace"); } }
    import javax.swing.*; public class RepairName { public static void main(String[] args) { String name, saveOriginalName; int stringLength; int i; char c; name = JOptionPane.showInputDialog(null, "Please enter your first and last name"); saveOriginalName = name; stringLength = name.length(); for(i=0; i < stringLength; i++) { c = name.charAt(i); if(i == 0) { c = Character.toUpperCase(c); name = c + name.substring(1, stringLength); } else if(name.charAt(i) == ' ') { ++i; c = name.charAt(i); c = Character.toUpperCase(c); name = name.substring(0, i) + c + name.substring(i + 1, stringLength); } } JOptionPane.showMessageDialog(null, "Original name was " + saveOriginalName + "\nRepaired name is " + name); } }
    import javax.swing.*; public class NumberInput { public static void main(String[] args) { String inputString; int inputNumber; int result; final int FACTOR = 10; inputString = JOptionPane.showInputDialog(null, "Enter a number"); inputNumber = Integer.parseInt(inputString); result = inputNumber * FACTOR; JOptionPane.showMessageDialog(null, inputNumber + " * " + FACTOR + " = " + result); } }
    public class StringBuilderMethods { public static void main(String[] args) { StringBuilder str = new StringBuilder("singing"); System.out.println(str); str.append(" in the dead of "); System.out.println(str); str.insert(0, "Black"); System.out.println(str); str.insert(5, "bird "); System.out.println(str); str.append("night"); System.out.println(str); } }
  7. Case Problems

    class Event { public final static double HIGH_GUEST_PRICE = 35.00; public final static double LOW_GUEST_PRICE = 32.00; public final static int LARGE_EVENT = 50; public final static int EVENT_NUM_LENGTH = 4; private String eventNumber; private int guests; private double pricePerGuest; private double priceForEvent; private String contactPhone; public Event() { this("A000", 0); } public Event(String num, int guests) { setEventNumber(num); setGuests(guests); } public void setEventNumber(String num) { boolean numOk = true; if(num.length() != EVENT_NUM_LENGTH || !Character.isLetter(num.charAt(0)) || !Character.isDigit(num.charAt(1)) || !Character.isDigit(num.charAt(2)) || !Character.isDigit(num.charAt(3))) eventNumber = "A000"; else eventNumber = num.toUpperCase(); } public void setGuests(int gsts) { guests = gsts; if(isLargeEvent()) { pricePerGuest = LOW_GUEST_PRICE; priceForEvent = guests * LOW_GUEST_PRICE; } else { pricePerGuest = HIGH_GUEST_PRICE; priceForEvent = guests * HIGH_GUEST_PRICE; } } public String getEventNumber() { return eventNumber; } public int getGuests() { return guests; } public double getPriceForEvent() { return priceForEvent; } public double getPricePerGuest() { return pricePerGuest; } public String getContactPhone() { String phone; phone = "(" + contactPhone.substring(0, 3) + ") " + contactPhone.substring(3, 6) + "-" + contactPhone.substring(6, 10); return phone; } public void setContactPhone(String phone) { final int VALID_LEN = 10; final String INVALID_PHONE = "0000000000"; contactPhone = ""; int len = phone.length(); for(int x = 0; x < len; ++x) { if(Character.isDigit(phone.charAt(x))) contactPhone += phone.charAt(x); } if(contactPhone.length() != VALID_LEN) contactPhone = INVALID_PHONE; } public boolean isLargeEvent() { boolean isLarge = false; if(guests >= LARGE_EVENT) isLarge = true; return isLarge; } }
    import java.util.Scanner; public class EventDemo { public static void main(String[] args) { String eventNum; int guests; eventNum = getEventNumber(); guests = getGuests(); Event e1 = new Event(eventNum, guests); e1.setContactPhone(getPhone()); eventNum = getEventNumber(); guests = getGuests(); Event e2 = new Event(eventNum, guests); e2.setContactPhone(getPhone()); eventNum = getEventNumber(); guests = getGuests(); Event e3 = new Event(eventNum, guests); e3.setContactPhone(getPhone()); displayDetails(e1); displayDetails(e2); displayDetails(e3); Event larger = new Event(); larger = getLarger(e1, e2); System.out.println("\nOf Event #" + e1.getEventNumber() + " with " + e1.getGuests() + " guests " + " and Event #" + e2.getEventNumber() + " with " + e2.getGuests() + "\n the larger is Event #" + larger.getEventNumber() + " with " + larger.getGuests()); larger = getLarger(e1, e3); System.out.println("\nOf Event #" + e1.getEventNumber() + " with " + e1.getGuests() + " guests " + " and Event #" + e3.getEventNumber() + " with " + e3.getGuests() + "\n the larger is Event #" + larger.getEventNumber() + " with " + larger.getGuests()); larger = getLarger(e2, e3); System.out.println("\nOf Event #" + e2.getEventNumber() + " with " + e2.getGuests() + " guests " + " and Event #" + e3.getEventNumber() + " with " + e3.getGuests() + "\n the larger is Event #" + larger.getEventNumber() + " with " + larger.getGuests()); for(int x = 0; x < e1.getGuests(); ++x) System.out.println("Please come to my event!"); } public static String getEventNumber() { String num; Scanner input = new Scanner(System.in); System.out.print("Enter event number >> "); num = input.nextLine(); return num; } public static int getGuests() { int guests; final int MIN_GUESTS = 5; final int MAX_GUESTS = 100; Scanner input = new Scanner(System.in); System.out.print("Enter number of guests >> "); guests = input.nextInt(); while(guests < MIN_GUESTS || guests > MAX_GUESTS) { System.out.println("The number of guests must be between " + MIN_GUESTS + " and " + MAX_GUESTS); System.out.print("Please renter >> "); guests = input.nextInt(); } input.nextLine(); return guests; } public static void displayDetails(Event e) { System.out.println("\nEvent #" + e.getEventNumber()); System.out.println("The price for an event with " + e.getGuests() + " guests at $" + e.getPricePerGuest() + " per guest is $" + e.getPriceForEvent()); System.out.println("Whether this is a large event is " + (e.getGuests() >= e.LARGE_EVENT)); System.out.println("Contact phone number is: " + e.getContactPhone()); } public static Event getLarger(Event e1, Event e2) { Event larger = e2; if(e1.getGuests() >= e2.getGuests()) larger = e1; return larger; } public static String getPhone() { String phone; Scanner input = new Scanner(System.in); System.out.print("Enter contact phone number >> "); phone = input.nextLine(); return phone; } }
    class Rental { public static final int MINUTES_IN_HOUR = 60; public static final int HOUR_RATE = 40; public static final int CONTRACT_NUM_LENGTH = 4; private String contractNumber; private int hours; private int extraMinutes; private double price; private String contactPhone; public Rental(String num, int minutes) { setContractNumber(num); setHoursAndMinutes(minutes); } public Rental() { this("A000", 0); } public void setContractNumber(String num) { boolean numOk = true; if(num.length() != CONTRACT_NUM_LENGTH || !Character.isLetter(num.charAt(0)) || !Character.isDigit(num.charAt(1)) || !Character.isDigit(num.charAt(2)) || !Character.isDigit(num.charAt(3))) contractNumber = "A000"; else contractNumber = num.toUpperCase(); } public void setHoursAndMinutes(int minutes) { hours = minutes / MINUTES_IN_HOUR; extraMinutes = minutes % MINUTES_IN_HOUR; if(extraMinutes <= HOUR_RATE) price = hours * HOUR_RATE + extraMinutes; else price = hours * HOUR_RATE + HOUR_RATE; } public String getContractNumber() { return contractNumber; } public int getHours() { return hours; } public int getExtraMinutes() { return extraMinutes; } public double getPrice() { return price; } public String getContactPhone() { String phone; phone = "(" + contactPhone.substring(0, 3) + ") " + contactPhone.substring(3, 6) + "-" + contactPhone.substring(6, 10); return phone; } public void setContactPhone(String phone) { final int VALID_LEN = 10; final String INVALID_PHONE = "0000000000"; contactPhone = ""; int len = phone.length(); for(int x = 0; x < len; ++x) { if(Character.isDigit(phone.charAt(x))) contactPhone += phone.charAt(x); } if(contactPhone.length() != VALID_LEN) contactPhone = INVALID_PHONE; } }
    import java.util.Scanner; public class RentalDemo { public static void main(String[] args) { String contractNum; int minutes; contractNum = getContractNumber(); minutes = getMinutes(); Rental r1 = new Rental(contractNum, minutes); r1.setContactPhone(getPhone()); contractNum = getContractNumber(); minutes = getMinutes(); Rental r2 = new Rental(contractNum, minutes); r2.setContactPhone(getPhone()); contractNum = getContractNumber(); minutes = getMinutes(); Rental r3 = new Rental(contractNum, minutes); r3.setContactPhone(getPhone()); displayMotto(); displayDetails(r1); displayDetails(r2); displayDetails(r3); System.out.println("Of Contract #" + r1.getContractNumber() + " with a time of " + r1.getHours() + " hours and " + r1.getExtraMinutes() + " minutes,\n and Contract #" + r2.getContractNumber() + " with a time of " + r2.getHours() + " hours and " + r2.getExtraMinutes() + " minutes,\n the one with the longer time is Contract #" + getLongerRental(r1, r2).getContractNumber()); System.out.println("Of Contract #" + r1.getContractNumber() + " with a time of " + r1.getHours() + " hours and " + r1.getExtraMinutes() + " minutes,\n and Contract #" + r3.getContractNumber() + " with a time of " + r3.getHours() + " hours and " + r3.getExtraMinutes() + " minutes,\n the one with the longer time is Contract #" + getLongerRental(r1, r3).getContractNumber()); System.out.println("Of Contract #" + r2.getContractNumber() + " with a time of " + r2.getHours() + " hours and " + r2.getExtraMinutes() + " minutes,\n and Contract #" + r3.getContractNumber() + " with a time of " + r3.getHours() + " hours and " + r3.getExtraMinutes() + " minutes,\n the one with the longer time is Contract #" + getLongerRental(r2, r3).getContractNumber()); int hoursInRental = r1.getHours(); for(int x = 0; x < hoursInRental; ++x) System.out.println("Coupon good for 10 percent off next rental"); } public static String getContractNumber() { String num; Scanner input = new Scanner(System.in); System.out.print("Enter contract number >> "); num = input.nextLine(); return num; } public static int getMinutes() { int minutes; final int LOW_MIN = 60; final int HIGH_MIN = 7200; Scanner input = new Scanner(System.in); System.out.print("Enter minutes >> "); minutes = input.nextInt(); while(minutes < LOW_MIN || minutes > HIGH_MIN) { System.out.println("Time must be between " + LOW_MIN + " minutes and " + HIGH_MIN + " minutes"); System.out.print("Please reenter minutes >> "); minutes = input.nextInt(); } return minutes; } public static void displayDetails(Rental r) { System.out.println("\nContract #" + r.getContractNumber()); System.out.println("For a rental of " + r.getHours() + " hours and " + r.getExtraMinutes() + " minutes,\n at a rate of $" + r.HOUR_RATE + " per hour and $1 per minute,\n the price is $" + r.getPrice()); System.out.println("Contact phone number is: " + r.getContactPhone()); } public static void displayMotto() { System.out.println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); System.out.println("S S"); System.out.println("S Sammy's makes it fun in the sun. S"); System.out.println("S S"); System.out.println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"); } public static Rental getLongerRental(Rental r1, Rental r2) { Rental longer = new Rental(); int minutes1; int minutes2; minutes1 = r1.getHours() * Rental.MINUTES_IN_HOUR + r1.getExtraMinutes(); minutes2 = r2.getHours() * Rental.MINUTES_IN_HOUR + r2.getExtraMinutes(); if(minutes1 >= minutes2) longer = r1; else longer = r2; return longer; } public static String getPhone() { String phone; Scanner input = new Scanner(System.in); System.out.print("Enter contact phone number >> "); phone = input.nextLine(); return phone; } }