Contents:

Goal

In Problem Set 0, you were introduced to various tools you will use throughout the quarter, including Eclipse, SVN, and JUnit. The purpose of these optional problems is to provide additional background on the basics of Java and additional exercises which you can work on at your own pace. Each problem begins with links to relevant readings on the Sun website, which will help you solve the corresponding questions. As with all assignments, it is a good idea to read an entire problem thoroughly before starting work to ensure you understand what is being asked.

Problem 1: Language Basics I

Readings: Language Basics

Look at the code below which calculates the value of investing an initial sum of money at a specified interest rate and for a specified number of years. Open the source file FinancialCalc.java:

public class FinancialCalc {

  public static void main(String[] args) {
    double principal = 1000.00;    // $1000 initial investment

    double interestRate = 0.035;   // 3.5% interest rate
    int numOfYears = 7;            // investment length is 7 years

    double value = 0.0;
    value = principal * Math.pow((1 + interestRate), numOfYears);
    System.out.println("Investing $" + principal +
                       " at an interest rate of " + (interestRate*100) + "%" +
                       " for " + numOfYears + " years" +
                       " will have a final worth of $" + value);
  }

}

Create a new class called MyFinancialCalc that calculates the following:

  1. The amount of money you should invest today (at an interest rate of 5%) to have a total amount of $1000.00 at the end of 4 years.
  2. The interest rate you need to turn an initial investment of $500.00 into $525.00 at the end of 3 years (hint: be careful when carrying out integer arithmetic--don't forget to cast variables if necessary).
  3. The number of years you need to invest an initial sum of $100.00 at an interest rate of 4.4% to have a final value of $150.00 (hint: the number of years is not necessarily an integer).

You should consider using the methods in the class java.lang.Math to aid your calculations. Remember that the value (V) of an investment (principal P) compounded yearly for Y years at interest rate I is given by the formula:

V = P * (1 + I)^Y

Note: we chose this problem as an introduction to Java language basics, including the math operators. However, the floating-point arithmetic used by the double and float types is in practice a very poor choice for financial calculations, because it is not exact. (You may notice, for example, that when you print out the interest rate that should be 4.4, that it prints out as 4.3999999999999995.) See item 31 in Effective Java for more information.

Problem 2: Language Basics II

Readings: Language Basics

Look at the method below which finds prime numbers. Open the source file Primes.java:

public class Primes {

  private static void findPrimes(int nValues) {

    boolean isPrime = true;

    for (int i = 2; i ≤ nValues; i++) {
      isPrime = true;

      for (int j = 2; j < i; j++) {
        if (i % j == 0) {
          isPrime = false;
          break;

        }
      }

      if (isPrime) {
        System.out.println(i);
      }
    }
  }


  // REMAINING METHODS NOT SHOWN
}

Implement the new method findPrimesFaster in class Primes by copying the code from the findPrimes method and modifying it to have the following features:

Problem 3: Object Basics I

Readings: Object Basics and Simple Data Objects

In this problem you will implement the method findPrimesEvenFaster in the class Primes. You may want to look at the class ArrayList. Your implementation should take the following into account:

Did you notice anything strange when you ran the program? Observe how fast each method takes to perform the task.

Problem 4: Object Basics II

Readings: Object Basics and Simple Data Objects

Write a new class called StringScrambler that takes a String as input and reverses the order of all words found in the String. So for example:

Assume for this problem that a word consists of consecutive characters (letters, numbers, and punctuation) not separated by whitespace. Also assume that all words in the input string have at most one space between them, and that the input string has no initial or trailing spaces. So for example, the following sentence violates all three assumptions:

"  This sentence starts with two initial spaces, has more than one
space     in between words, and ends with a trailing
space "

Complete the skeleton implementation of the class StringScrambler. You may want to look at the method split() and the classes StringBuilder and Arrays. Feel free to define as many helper methods as you need.

Problem 5: Classes and Inheritance

Readings: Classes and Inheritance

We define a basic class for point objects. Open the source file Point.java:

class Point {

  double x;
  double y;

  // Create a point from coordinates
  Point(double xVal, double yVal) {
    x = xVal;
    y = yVal;
  }

}

Use the Point objects to define a class Line. Include a constructor to create a line from two points, a method length to calculate the length of a line, and a toString method to print out a description of the line.

Finally, write a method intersects, called from a Line object, which returns a point as the intersection of two lines (view resource for intersection point of two lines).

Problem 6: Collections and Iterators

Readings: Sun's overview of the Collections framework

Java provides an extensive framework for dealing with collections of things. A framework is a group of tightly interacting classes that together provide a set of functionality. In this case, the functionality is storing, viewing, modifying, and searching through Collections, like ordered lists, unordered sets, and several others. All of the framework classes are in the package java.util. It is important to be familiar with the classes in the Collections framework as they will come in useful in many situations. In addition, we would like you to get some practice with for/in loops and Iterators and in the process understand the subtle differences between them.

Take a look at the source code file Card.java, which defines a playing card. Since playing cards have two attributes - a suit and a value, we implement these in CardValue.java and CardSuit.java. Both these attributes are implemented as enumerated types, i.e., enums. Why do you think we did this instead of representing these attributes as integers in Card.java?

Notice that Card implements Comparable<Card>, an interface that requires Cards to implement the method compareTo(Card). By doing so, we can use methods in the Collections class to perform useful operations on a set (deck) of cards.

Suppose we want to implement a playing hand, i.e., a small set of cards, called MyHand. The skeleton code is provided in MyHand.java. First, browse through the javadoc for the classes that implement the Collection interface. Notice that a LinkedList was used in the implementation of MyHand. Do you think that this was a good choice? Why? If not, what would you suggest? The point here is to highlight that even though many of the Collection classes implement similar functionality, there are subtle differences in the operational efficiencies of the underlying implementations for different methods.

  1. Implement a method printHand(Collection<Card> hand) that prints the hand to the screen. (Hint: Read about the for/in loop in your notes.)
  2. When playing cards, it is natural for a player to want to sort his cards in some order. Fill in the code to implement a method that will sort the cards (first by value, then by suit) and also one that will sort the cards in reverse order. They are called sortSmallestToLargest() and sortLargesttoSmallest() respectively. (Hint: since Card implements Comparable, this task is trivial if you invoke the appropriate methods in the Collections class.)
  3. Suppose that whenever we print the playing hand we only want to display the hearts. Fill in the code to implement the method printHand_OnlyHearts(Collection<Card> hand) that achieves this. Can you use the for/in loop here? Why/why not?
  4. Finally, suppose we only want to display numbered cards (non Face Cards) and furthermore, want to remove face cards from the hand. Fill in the code to implement the method printHand_RemoveFaceCards(Collection<Card> hand) that achieves this. Can you still use the for/in loop here? Why/why not? (Hint: Read about the remove() method in Iterator.)