
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

/**
 * A class to demonstrate the non-safe and safe ways of returning a List to
 * client programs. The object remembers words entered by the user, but rejects
 * nulls and words starting with the letter F (upper- or lower-case).  Words
 * can't be removed after they've been added.
 *
 * getWordsUnsafe() returns a reference to the List, allowing the client to 
 * mess with its contents -- VIOLATING our contract.
 *
 * getWordsCopy() returns a copy of the list, keeping us safe from the client,
 * at the cost of doing a copy.
 *
 * getWordsSafe() returns our list wrapped in an unmodifiable list object,
 * keeping us safe from the client without having to make a copy.
 *
 * @author Mark Young (A00000000)
 */
public class PrivateList {

    private final List<String> myWords;

    /**
     * Create a new, empty list.
     */
    public PrivateList() {
        myWords = new ArrayList<>();
    }

    /**
     * Add the given word to this list.  Reject nulls and words starting with F
     * (whether lower-case or upper-case).
     *
     * @param newWord the word to add.
     * @return true if the word was added; false otherwise.
     */
    public boolean addWord(String newWord) {
        // don't allow nulls or f-words
        if (newWord == null || newWord.toUpperCase().startsWith("F")) {
            return false;
        }
        myWords.add(newWord);
        return true;
    }

    /**
     * Return the list of words -- IN AN UNSAFE WAY!  This method violates
     * encapsulation by allowing the client to add nulls or F-words, or remove
     * words that were previously added.
     *
     * @return the List of words.
     */
    public List<String> getWordsUnsafe() {
        // bad version
        return myWords;
    }

    /**
     * Return the list of words -- IN A SAFE WAY!  This method ensure that our
     * encapsulation works by returning a COPY of our List. Any changes the 
     * client makes will be to that copy, and not our original.
     *
     * @return the List of words.
     */
    public List<String> getWordsCopy() {
        return new ArrayList<>(myWords);
    }

    /**
     * Return the list of words -- IN A SAFE WAY!  This method ensure that our
     * encapsulation works by returning a List that the client can't modify at
     * all.
     *
     * @return the List of words.
     */
    public List<String> getWordsSafe() {
        return Collections.unmodifiableList(myWords);
    }

    /**
     * Create a String representation of this List.
     *
     * @return a String representing this List.
     */
    @Override
    public String toString() {
        return myWords.toString();
    }

}

