In this application, the programmer must often manipulate a collection of cards: the main deck, the player’s hand, the cards that are dealt, and the cards that user wants to discard. Having a speciﬁc data structure for a collection of cards will be useful when implementing the logic of the game. Accordingly, you must implement the class Deck following these instructions:
A Deck uses an object of the class java.util.ArrayList to store the cards of this deck. The class declares two constructors. One of them has no parameters. It is used when creating an empty deck. The other constructor has one parameter, of type int. The parameter speciﬁes the number of ranks for the cards. It also initializes this deck to contain 4 × n cards, where n is the value of the parameter. int size(): returns the number of cards in this deck. boolean hasCards(): returns true if and only if this deck has one or more cards. Card get(int pos): returns the card at the speciﬁed position in the deck. void add(Card card): adds the speciﬁed card at the end of this deck. void addAll(Deck other): appends all the cards from other at the end of this deck. The cards are also removed from other. Consequently, the deck designated by other is empty after the call. Card removeLast(): removes and returns the last card of this deck. Card removeFirst(): removes and returns the ﬁrst card of this deck. boolean remove(Card card): removes the ﬁrst occurrence of the speciﬁed card from this deck, if it is present. Returns true if and only if this deck contains the speciﬁed card. void removeAll(Deck other): removes from this deck all of its cards that are contained in the deck designated by the parameter other. The cards are not removed from the deck designated by other. void shuﬄe(): randomly permutes the cards. Deck deal(int n): removes a maximum of n cards from the end of this deck. The cards are returned in a new deck. boolean contains(Card card): returns true if and only if this deck contains the speciﬁed card. boolean containsAll(Deck other): returns trueif and only if this deck contains all the cards in the speciﬁed deck. boolean isKind(): returns true if and only if this deck is a discardable kind. Speciﬁcally, the method returns true if this deck has at least two cards and all the cards have the same rank. Otherwise, the method returns false. boolean isSeq(): returns true if and only if this deck is a discardable sequence. Speciﬁcally, the method returns true if this deck has at least three cards, the cards all have the same suit, the cards form a sequence of consecutive ranks. Otherwise, the method returns false. void sortBySuit(): sorts the cards of this deck by suit. void sortByRank(): sorts the cards of this deck by rank. void print(): prints the content of this deck in two ways. First, the content is printed by suit. Next, the content is printed by rank. Please note that this method has a side eﬀect, the order of the cards is not preserved. Consequently, the method should not be called on the main deck during a game! String toString(): returns a string representation that contains all the cards in this deck.