John Eakin John Eakin - 5 months ago 17
Java Question

Java - Creating Objects With ArrayList, Constructor Skipped 1st Iteration

I am in the process of writing a program for a game of Blackjack. So far, I can create an object with a suit, value, and a value as a String. I am experimenting with different ways of implementing my classes into the game. Unfortunately, when I use a loop to create multiple objects in an ArrayList, when the first object in the list is instantiated with its fields the constructor is repeated twice. This is a problem because an array that checks for duplicate cards relies on each object calling the constructor only once. This only occurs when using ArrayList; using a single object works properly. Provided below are my two classes, driver, and sample output. Please ignore most of the comments, this was copied directly and most of them are notes for myself.

So why is it repeating? How can this be fixed? TIA.

CARD CLASS

public class Card
{
private final String[] SUITS = {"Clubs", "Diamonds", "Hearts", "Spades"};
private final int[] VALUES = {2,3,4,5,6,7,8,9,10};

public String getSuits(int num)
{
return SUITS[num];
}
public int getValues(int num)
{
return VALUES[num];
}
}


DECK CLASS

import java.util.Random;
//import java.util.Arrays;

public class Deck extends Card
{
private String suit, valueString;
private int value, valueNum, suitNum;
private static int tot = 0;
private static boolean[][] duplicateCheck = new boolean[4][13];//to see if suit/value pair has been used yet //only fills up to 50 cards
static int times = 0;
Random rand = new Random();
Card transfer = new Card();

public Deck()//can the constructor just be a super() of the parent?
{
//System.out.println(Arrays.deepToString(duplicateCheck));
do
{
suitNum = rand.nextInt((3 - 0) + 1) + 0;
suit = transfer.getSuits(suitNum);
valueNum = rand.nextInt((12 - 0) + 1) + 0;
// System.out.println("CARD BELOW");
}
while(duplicateCheck[suitNum][valueNum] );

duplicateCheck[suitNum][valueNum] = true;
//System.out.println(duplicateCheck[suitNum][valueNum] + ", "+valueNum + " "+suitNum);
if(valueNum >= 9 && valueNum <= 11)
{
value = 11;
switch(valueNum)
{
case 9:
valueString = "Jack";
break;
case 10:
valueString = "King";
break;
case 11:
valueString = "Queen";
break;
default:
valueString = Integer.toString(valueNum);//not really needed
break;
}
}
else if(valueNum == 12)
{
if(tot + 11 > 21)
value = 1;
else
value = 11;
valueString = "Ace";
}
else
{
value = transfer.getValues(valueNum);
valueString = Integer.toString(transfer.getValues(valueNum));
}
tot += value;
System.out.println(valueString + ", " + suit + ", " + ++times);
}
public String getSuit()
{
return suit;
}
public int getValue()
{
return value;
}
public String getValueString()
{
return valueString;
}
//put into place a method that plays a new deck after each hand
}


DRIVER

import java.util.ArrayList;
public class DeckTester
{
public static void main(String[] args)
{
Deck temp = new Deck();
ArrayList<Deck> t = new ArrayList<>();//problem has to do with ArrayList, it works with a single object

for(int x = 0; x < 5; x++)//it doesnt display the first card
{
t.add(new Deck());
System.out.println(t.get(x).getValueString() + " of " + t.get(x).getSuit() + " " + x);
}

//System.out.println(temp.getValueString() + " of " + temp.getSuit());
}
}


OUTPUT

//the first set of value and suit is from the deck class+a counter to show the number of objects before it

5, Hearts, 1//notice the unused fields
King, Clubs, 2
King of Clubs
4, Diamonds, 3
4 of Diamonds
9, Clubs, 4
9 of Clubs
9, Spades, 5
9 of Spades
4, Hearts, 6
4 of Hearts

Answer Source

Your output is correct: The first line printed comes from the Deck temp = new Deck() when its constructor gets executed it printed System.out.println(valueString + ", " + suit + ", " + ++times);

5, Hearts, 1  from temp constructor

this prints down here come from both the constructor on each one and the print System.out.println(t.get(x).getValueString() + " of " + t.get(x).getSuit() + " " + x); within the for loop.

King, Clubs, 2  
King of Clubs
4, Diamonds, 3
4 of Diamonds
9, Clubs, 4
9 of Clubs
9, Spades, 5
9 of Spades
4, Hearts, 6
4 of Hearts

Now be aware that the constructor only gets executed only one time every time an object is created, it never gets executed twice your output print is misleading you.