Solution: Fields and Constructor
Before designing the operations of a bag, we need to decide how to represent the balls. The bag holds two colors: black and blue. We could store the color as a String[] balls, with "black" and "blue" as the values. We could use an int[] balls, with 0 for black and 1 for blue. We could even use a boolean[] balls, with false for black and true for blue. We could also create a Ball class with a color field, but that still leaves us choosing how to represent the color itself, so it just moves the problem rather than solving it.
What we want is a type whose only possible values are black and blue. That is exactly what an enum gives us:
public enum BallColor {
BLACK,
BLUE
}
We can then declare BallColor[] balls in our Bag class. An enum is a good choice whenever we have a fixed set of named constants, like the colors of balls in our bag. It makes the code more readable and less error-prone than encoding the same values as strings, integers, or booleans.
What is an enum?
An enum is a type whose values are a fixed set of named constants.
Here, BallColor has two values, BLACK and BLUE. Enums also come with some built-in features, like being able to iterate over their values or having a toString method. In Java, you can define an enum in its own file or as a static nested type inside another class. In this case, we might put BallColor in its own file for clarity, but it could also be a nested enum inside Bag if we wanted to keep it closely tied to that class.
To use an enum, we just refer to its values by name. For example, BallColor.BLACK and BallColor.BLUE are the two possible colors of balls we can have in our bag.
A bag is an abstraction over a fixed-size array whose storage grows on demand, so its state looks a lot like DynamicArray’s. There is a backing array of balls, and a size counting how many of its slots hold balls.
The one new field we add to this class is a Random object, which we use to draw a ball at random from the bag.
public class Bag {
private BallColor[] balls; // the underlying fixed-size storage
private int size; // how many balls are in the bag right now
private Random rng; // source of randomness for drawing a ball
public Bag() {
balls = new BallColor[10]; // start with room for 10 balls
size = 0; // but the bag starts empty
rng = new Random();
}
public int size() {
return size;
}
}
Random lives in java.util, so the file needs import java.util.Random; at the top.
All three fields are private, for the reason we gave for DynamicArray. The capacity and size have to stay consistent with the balls the array holds, and a client that could set size directly would break that.
Now the client needs a way to put a ball in the bag.