Sort arraylist in random order - java

I'm coding a cards game, I have an ArrayList holding cards (Object) where
each one of them has its id.
Since I want to make this game to support multiplayer mode,
I must in some way send/receive game progress between the 2 players.
Now, if I shuffled the cards on a side, I must do the same thing in the other but it will be a big packet to be sent since every card has an image.
What I thought is to send an integer array of the shuffled list, so it will be received on the other side and re-ordered following the integer array.
How can I send the shuffled order and apply it on the other side?

The Random class can be used for this.
If two instances of Random are created with the same seed, and the
same sequence of method calls is made for each, they will generate and
return identical sequences of numbers. In order to guarantee this
property, particular algorithms are specified for the class Random.
Java implementations must use all the algorithms shown here for the
class Random, for the sake of absolute portability of Java code.
This means that you can transmit only the seed value to the client, instantiate a new Random instance using it and expect to receive the same sequence of random numbers as on the other player's machine.
Collections.shuffle can be invoked with a Random source.

Although it is possible to initialize two java.util.Random instance with the same seed, and use these instances with Collections.shuffle() as mentioned by Henrik. The only problem is that Collections.shuffle() calls with these instances have to be called in the same sequence (i.e. synchronized). It may not be possible to guarantee this, for example if one player requests card shuffle more than one in very quick succession, and the other player falls out of sync (due to network issues).
One alternative is to do the sorting manually on both ends. An illustration is given below.
public class Card {
private final int id;
private final String imageURL;
public Card(int id, String imageURL) {
this.id = id;
this.imageURL = imageURL;
}
public int getId() {
return id;
}
public String getImageURL() {
return imageURL;
}
/**
* Getters and setters below
*/
}
public class Example {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
final int NUMBER_OF_CARDS = 6;
//
final List<Card> originalList = new ArrayList<>();
//
for (int i = 1; i <= NUMBER_OF_CARDS; i++) {
originalList.add(new Card(i, "image_url"));
}
//Create player card list
final List<Card> firstPlayerCardsList = new ArrayList<>(originalList);
final List<Card> secondPlayerCardsList = new ArrayList<>(originalList);
//
//1. Shuffle list on one side
Collections.shuffle(firstPlayerCardsList);
//
//2. Iterate over the list and add indices to array
final int[] indices = new int[NUMBER_OF_CARDS];
//note indices are zero based to allign with arrays
for (int i = 0; i < NUMBER_OF_CARDS; i++) {
indices[i] = firstPlayerCardsList.get(i).getId();
}
//
// 3. Send the shuffle indices array across to second player
// ********* omitted ******
//
// 4. Recreate the shuffle order at the second players end, based on the shuffle indices array
final List<Card> tempCardsList = new ArrayList<>(secondPlayerCardsList);
secondPlayerCardsList.clear();
IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
final int id = indices[index];
for (final Card c : tempCardsList) {
if (c.getId() == id) {
secondPlayerCardsList.add(c);
}
}
// can also use in place of the above
//tempCardsList.stream().filter((c) -> (c.getId() == id)).forEachOrdered((c) -> {
// secondPlayerCardsList.add(c);
//});
});
// Show the results for this illustration
System.out.println(" Original" + " First" + " Second");
IntStream.range(0, NUMBER_OF_CARDS).forEach((int index) -> {
System.out.println("\t" + originalList.get(index).getId() +"\t" + firstPlayerCardsList.get(index).getId() + "\t" + secondPlayerCardsList.get(index).getId());
});
}
}

Yes, just initialise and store the cards in an read-only array of 52 Card objects at the start of both sides:
final Card[] allCards = new Card[52] {...};
Use this array exclusively in the whole application on both sides to refer to each card using just an int index instead of a Card instance.
Then you'll have a deck object which is an int[52]. Initially, it will contain all the numbers from 0 to 51. Then you shuffle the array. Then you send the array of ints to the other side, and the other side then has the same shuffled deck.

Related

How to Perform Percentage on item list Enum? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm looking for some tip on how to do a percentage thing for my game I want all flowers in a range of 1-98 and white/black flowers 99-100 to make it more rarerity thanks for the help :)
public enum FlowerSuit {
WHITE_FLOWERS("white", ":white:", "470419377456414720", 1),
YELLOW_FLOWERS("yellow", ":yellow:", "470419561267855360", 1 ),
RED_FLOWERS("red", ":red:", "470419583250202644", 1),
RAINBOW_FLOWERS("rainbow", ":rainbow:", "470419602841665536", 1),
PASTEL_FLOWERS("pastel", ":pastel:", "470419629450199040", 1),
ORANGE_FLOWERS("orange", ":orange:", "470419647900942366", 1),
BLUE_FLOWERS("blue", ":blue:", "470419688753594368", 1),
BLACK_FLOWERS("black", ":black:", "470419706751352842", 1);
private final String displayName;
private final String emoticon;
private int value;
private final String id;
FlowerSuit(String displayName, String emoticon, String id, int value ) {
this.displayName = displayName;
this.emoticon = emoticon;
this.value = value;
this.id = id;
}
public String getDisplayName() {
return displayName;
}
public String getEmoticon() {
return emoticon;
}
public String getId() {
return id;
}
public int getValue() {
// TODO Auto-generated method stub
return value;
}
}
This is how I'd do it, but it can probably be improved, for starters by using Java 8 streams etc.
public enum FlowerSuit {
WHITE_FLOWERS("white", ":white:", "470419377456414720", 1,3),
YELLOW_FLOWERS("yellow", ":yellow:", "470419561267855360", 1,2),
RED_FLOWERS("red", ":red:", "470419583250202644", 1,2),
RAINBOW_FLOWERS("rainbow", ":rainbow:", "470419602841665536", 1,2),
PASTEL_FLOWERS("pastel", ":pastel:", "470419629450199040", 1,2),
ORANGE_FLOWERS("orange", ":orange:", "470419647900942366", 1,2),
BLUE_FLOWERS("blue", ":blue:", "470419688753594368", 1,2),
BLACK_FLOWERS("black", ":black:", "470419706751352842", 1,1);
private static Random random = new Random();
private final String displayName;
private final String emoticon;
private int value;
private final String id;
private final int freq;
private FlowerSuit(String displayName, String emoticon, String id, int value, int freq ) {
this.displayName = displayName;
this.emoticon = emoticon;
this.value = value;
this.id = id;
this.freq = freq;
}
public String getDisplayName() {return displayName;}
public String getEmoticon() {return emoticon;}
public String getId() {return id;}
public int getValue() {return value;}
/**
* Choose a flower
* white has a 3 in 16 (about a 5:1) chance of being picked
* Black has a 1 in 16 chance, everything else 2/16
* #return
*/
public static FlowerSuit pick() {
//first sum all the chances (currently it's 16)
int sum = 0;
for (FlowerSuit f:FlowerSuit.values()) sum+= f.freq;
//now choose a random number
int r = FlowerSuit.random.nextInt(sum) + 1;
//now find out which flower to pick
sum = 0;
for (FlowerSuit f:FlowerSuit.values()) {
sum += f.freq;
if (r<=sum) return f;
}
//code will never get here
return FlowerSuit.WHITE_FLOWERS;
}
public static void main(final String[] args) throws Exception {
//Test it
Map<FlowerSuit,Integer>count = new HashMap<FlowerSuit,Integer>();
for (int a=0;a<1000000;a++) {
FlowerSuit f = FlowerSuit.pick();
Integer i = (count.get(f)!=null)?count.get(f):new Integer(0);
i = new Integer(i+1);
count.put(f,i);
}
int sum = 0;
for (Map.Entry<FlowerSuit,Integer>e:count.entrySet()) sum+=e.getValue();
float f = Float.valueOf(sum);
for (Map.Entry<FlowerSuit,Integer>e:count.entrySet()) {
System.out.println(e.getKey() + " was chosen " + ((e.getValue() / f) * 100f) + "% of the time");
}
}
}
gives
BLUE_FLOWERS was chosen 12.4986% of the time
PASTEL_FLOWERS was chosen 12.4707% of the time
WHITE_FLOWERS was chosen 18.7365% of the time
BLACK_FLOWERS was chosen 6.2632003% of the time
ORANGE_FLOWERS was chosen 12.4986% of the time
RED_FLOWERS was chosen 12.5241995% of the time
YELLOW_FLOWERS was chosen 12.501401% of the time
RAINBOW_FLOWERS was chosen 12.5068% of the time
You can use a TreeMap to map all of the integers from 0 to 99 to a particular FlowerSuit. Take advantage of the floorEntry method to choose a FlowerSuit for each number. It might look something like this.
public class FlowerChooser {
private static final NavigableMap<Integer, FlowerSuit> FLOWER_SUITS;
private static final Random RANDOMS = new Random();
public FlowerChooser() {
FLOWER_SUITS = new TreeMap<>();
FLOWER_SUITS.put(0, FlowerSuit.RED_FLOWERS);
FLOWER_SUITS.put(14, FlowerSuit.ORANGE_FLOWERS);
FLOWER_SUITS.put(28, FlowerSuit.YELLOW_FLOWERS);
FLOWER_SUITS.put(42, FlowerSuit.GREEN_FLOWERS);
FLOWER_SUITS.put(56, FlowerSuit.BLUE_FLOWERS);
FLOWER_SUITS.put(70, FlowerSuit.INDIGO_FLOWERS);
FLOWER_SUITS.put(84, FlowerSuit.VIOLET_FLOWERS);
FLOWER_SUITS.put(98, FlowerSuit.WHITE_FLOWERS);
FLOWER_SUITS.put(99, FlowerSuit.BLACK_FLOWERS);
}
public FlowerSuit randomFlowerSuit() {
int index = RANDOMS.nextInt(100);
return FLOWER_SUITS.floorEntry(index).getValue();
}
}
Create just one object of this class, then whenever you want a FlowerSuit, call the randomFlowerSuit method.
The randomFlowerSuit method picks a random number from 0 to 99, then finds an appropriate entry in the map. The floorEntry method chooses an entry whose key is less than or equal to the chosen number. This means that numbers from 0 to 13 get mapped to red, 14 to 27 get mapped to orange, and so on. The only number that gets mapped to white is 98, and the only number that gets mapped to black is 99.
No matter what solution you implement, you want to include a frequency measure in your enum. As an example, you can do something like this:
public enum FlowerSuit {
WHITE_FLOWERS("white", ":white:", "470419377456414720", 1, 1),
YELLOW_FLOWERS("yellow", ":yellow:", "470419561267855360", 1, 20),
// More declarations here
// Add this variable
private final int frequency;
// Do just as you did before in the constructor, but with the frequency
FlowerSuit(String displayName, String emoticon, String id, int value, int frequency){
this.frequency = frequency;
// More assignments here
}
public int getFrequency(){
return frequency;
}
// More getters here
}
This addition is critical, and no matter what method you use to weight flower selection, you will want this addition to your FlowerSuit enum.
Now, we can explore a few different ways to perform this selection.
Note 1: I use ThreadLocalRandom for random numbers in a range, which is from java.util.concurrent.ThreadLocalRandom.
Note 2: For each of these, make a single instance of FlowerPicker, and use the pickFlower() method to pick the next flower. This avoid running costly setup code over and over.
Method 1: Bag of Flowers
This method is probably the easiest to implement. It entails creating a list of enums where each is represented frequency times, and then selecting a random entry from this list. It is similar to throwing a bunch of flowers in a bag, shaking it, and then reaching your hand in and grabbing the first flower you touch. Here's the implementation:
public class FlowerPicker(){
private ArrayList<FlowerSuit> bag;
public FlowerPicker(){
// Get all possible FlowerSuits
FlowerSuit[] options = FlowerSuit.values();
// You can use an array here or an array list with a defined length if you know the total of the frequencies
bag = new ArrayList<FlowerSuit>();
// Add each flower from options frequency times
for (FlowerSuit flower : options)
for (int i=0; i<flower.getFrequency(); i++)
bag.add(flower);
}
public FlowerBag pickFlower(){
// Now, select a random flower from this list
int randomIndex = ThreadLocalRandom.current().nextInt(0, bag.size());
return bag.get(randomIndex);
}
}
This method has the advantage of being simple enough to understand very easily. However, it can be inefficient if your frequencies are extremely specific (like if you want a rainbow flower to be returned 499,999,999 times out of 1,000,000,000). Let's move on to the next method.
Note 1: You could make this better by reducing the fractions representing the frequency of being chosen, but I'll leave this to you.
Note 2: You could also make this slightly better by storing identification numbers, not FlowerSuit objects in the bag list.
Method 2: Navigable Map
This method is a little bit more difficult. It uses a [NavigableMap][1], which is an implementation of [TreeMap][2]. This method is fairly similar to the Bag of Flowers method, but it is a little bit more efficient. Put simply, it uses the TreeMap to give each FlowerSuit a range of numbers that can be selected to return that FlowerSuit. Here's a full example:
public class FlowerPicker(){
private NavigableMap<Double, FlowerSuit> map;
public FlowerPicker(){
// Get all possible FlowerSuits
FlowerSuit[] options = FlowerSuit.values();
map = new TreeMap<Double, FlowerSuit>();
int runningTotal = 0;
// Add each flower with the proper range
for (FlowerSuit flower : options){
runningTotal += flower.getFrequency();
map.put(runningTotal, flower);
}
}
public FlowerBag pickFlower(){
// Now, select a random number and get the flower with this number in its range
int randomRange = ThreadLocalRandom.current().nextInt(0, bag.size());
return map.higherEntry(randomRange).getValue();
}
}
This is a solid method, and it scales well for very specific frequencies. If you have a bunch of different types of flowers, it will be slightly worse, but this method is still a good option at large scales. There's one more option though.
Method 3: Enumerated Distribution
This method is really nice because you barely have to do anything. However, it uses [EnumeratedDistribution][3] from Apache Commons. Enumerated Distribution requires a list of pairs of objects and weights. Anyway, lets jump into it:
public class FlowerPicker(){
private EnumeratedDistribution distribution;
public FlowerPicker(){
// Get all possible FlowerSuits
FlowerSuit[] options = FlowerSuit.values();
List<Pair<FlowerSuit, Double>> weights = new List<Pair<FlowerSuit, Double>>();
// Add each flower and weight to the list
for (FlowerSuit flower : options){
weights.add(new Pair(flower, flower.getFrequency()));
// Construct the actual distribution
distribution = new EnumeratedDistribution(weights);
}
public FlowerBag pickFlower(){
// Now, sample the distribution
return distribution.sample();
}
}
This is my favorite method, simply because so much of it is done for you. Many problems like this have been solved, so why not use solutions that always exist? However, there is some value to writing the solution yourself.
In conclusion, each of these methods are perfectly fine to use at your scale, but I would recommend the second or third method.

When attempting to pass an int to determine array size in an array wrapped in an object, code does not execute depending on int size?

This is my third java course and we're reviewing sorting algorithms. I am using Eclipse to compile and run my code. I have an array wrapped in a class as such:
class ArrayBub
{
private long[] a; // ref to array a
private int nElems; // number of data items
public ArrayBub(int max) // constructor
{
a = new long[max]; // create the array
nElems = 0; // no items yet
}
public void insert(long value) // put element into array
{
a[nElems] = value; // insert it
nElems++; // increment size
}
...
public void display() // displays array contents
{
for(int j=0; j<nElems; j++) // for each element,
System.out.print(a[j] + " "); // display it
System.out.println("");
}
// there are other methods not listed here
The assignment is to pass an integer of at least 10000 into the constructor to create an array of this size. I am to observe how long it takes to insert this many values into each array index, along with how long it takes to bubble sort this array. The bubble sort method is not listed above.
My main method so far looks like this:
class BubbleSortApp
{
public static void main(String[] args)
{
int maxSize = 10000; // array size
ArrayBub arr; // reference to array
long n = 0;
arr = new ArrayBub(maxSize); // create the array
for (int j=0; j < maxSize; j++) {
n = (long) ((java.lang.Math.random()) * (maxSize - 1) );
arr.insert(n);
}
arr.display(); // display items
System.out.print("\n Done.");
// arr.bubbleSort(); // bubble sort them
// arr.display(); // display them again
} // end main()
} // end class BubbleSortApp
I have the bubblesort and second display methods commented out so i can just test inserting the large amount of elements.
My issue is that when attempting to pass maxSize = 10000 into the constructor and then execute, the array printout does not display and instead the "Done." prompt simply appears. I've tried altering maxSize to a smaller int, say 1000, which seems to work. When i try increasing maxSize, however, it seems to work arbitrarily. For some values the array displays fine, for other it doesn't. I've had instances where the same maxSize value causes the array printout to display on one run and not display on another.
I'm pretty puzzled. It seems to have something to do with the value of maxSize, but Eclipse is not showing any compile or runtime errors and I've already tried putting everything into try/catch blocks to weed anything else out.
There is an open bug with long lines not being displayed:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=23406
Try to either replace print with println or insert newline characters every now and then.

Creating an ArrayList of Arrays with predetermined length

Essentially, I'm looking to create an ArrayList of Arrays of Notes:
/**
* Represents the entire musical score, with each index of the ArrayList representing each beat.
* Each array of notes represent the notes that can play on a single beat (up to 120 notes, 12
* notes over 10 octaves.
*/
private List<Note[]> score;
...
score = new ArrayList<>(8); // Initialize ArrayList with capacity of 8
The first (minor) problem I'm running into here is first that the ArrayList could end up being any size and may have to grow many times (which doubles the size each time it requires additional capacity), and the second (more important) problem is that I'm unable to set the length of the Arrays contained within the ArrayList to 120 as follows:
private List<Note[120]> score;
This brings me to the question of how I can initialize all of the Arrays that may or may not exist in the ArrayList (because we don't know when/if/how often the ArrayList size may change) to a size of 120, and, if that is not possible, whether or not there is potentially a better data structure to be used in this situation. Thanks!
There is no data type for an array of length 120, so you cannot have a List<Note[120]> or a List<Note[]> where every array is guaranteed to have length 120. What you can do is make your own class:
public final class TenOctaves {
private static final int NUMBER_OF_NOTES = 120;
private final Note[] notes = new Note[NUMBER_OF_NOTES];
public void setNote(int position, Note note) {
if (position < 0 || position >= NUMBER_OF_NOTES)
throw new IllegalArgumentException();
notes[position] = note;
}
public Note getNote(int position) {
if (position < 0 || position >= NUMBER_OF_NOTES)
throw new IllegalArgumentException();
return notes[position];
}
}
Then you could have a List<TenOctaves> instead.
If I'm understanding you correctly, you could do with subclassing ArrayList and implementing your own special add logic.
public class NoteList extends ArrayList<Note[]> {
private final int SCORE_LENGTH = 120;
private final int MAX_ELEMENTS = 8;
#Override
public boolean add(Note[] score) {
return this.size() <= MAX_ELEMENTS && score.length == SCORE_LENGTH && super.add(score);
}
}
You won't be able to add elements to the list if:
the size of the list is larger than 8
the length of the array you're going to add is not 120

Creating a method that works like ArrayList .add()

I'm writing a program that acts as a 'pocket' where the user is able to enter a kind of coin, such as, a quarter and the amount of quarters it has. I was assigned to do 3 different class, the Coin Class in which the coins and their values can be instatiated from, a Pocket Class, where I have to write a method that can add the coins of the user (basically the method would act like ArrayList .add() ) and the PocketClass tester. I have already written most of the code, but I am stuck as to how I could write the following method:
public void addCoin(String s, int i)
{
// s is type of coin, you are using s to instantiate a Coin and get value
// i is number of coins, you are using i to keep adding value to the totalValue
}
My question is how should I approach this? I am not quite clear on how to create method. Would I use a for-loop in order to keep track of the number of coins? I understand that the addCoin method works a lot like .add() from ArrayList.
Here is the code from my other classes:
public class Coin
{
private final String DOLLAR = "DOLLAR";
private final String QUARTER = "QUARTER";
private final String DIME = "DIME";
private final String NICKEL = "NICKEL";
private final String PENNY = "PENNY";
private int value;
private String coinName;
public Coin(String s,int count)//name of the coin and also the number of the coins you have
{
//Use if or switch statement to identify incoming string and provide value
double value=0;
if(DOLLAR.equalsIgnoreCase(s))
{
value=100.0;
}
else if(QUARTER.equalsIgnoreCase(s))
{
value=25.0;
}
else if(DIME.equalsIgnoreCase(s))
{
value=10.0;
}
else if(NICKEL.equalsIgnoreCase(s))
{
value=5.0;
}
else if(PENNY.equalsIgnoreCase(s))
{
value=1.0;
}
}
public int getValue()
{
return value;
}
}
and how the Pocket class is structured:
public class Pocket
{
private int currentValue;
private int totalValue;
private Coin quarter;
private Coin dime;
private Coin nickle;
private Coin penny;
public Pocket()
{ //Set initial value to zero
totalValue = 0;
currentValue = 0;
}
public void addCoin(String s, int i)
{
// s is type of coin, you are using s to instantiate a Coin and get value
// i is number of coins, you are using i to keep adding value to the totalValue
}
public int getValue()
{
return totalValue;
}
public void printTotal()
{
//print out two different output
}
}
I'm assuming you're adding the addCoin method in the Pocket class.
If you intend to keep track of the number of coins of each type within a Pocket, the simplest way to do so would be to declare a Hashmap that is keyed by the coin type (say, a "quarter" or a "dollar") and valued by the number of coins of that type. An invocation of the addCoin(type, count) method, say addCoin("dollar", 5) can then check if the hashmap already contains a key named "dollar" and if present, increment it's value by count.
I would suggest storing coins in a list so that you can add unlimited number of them.
Example:
class Coin{
//Same as your code....
public Coin(String coinType){
//..Same as your code, but removed number of coins
}
}
public class Pocket
{
private int currentValue;
private int totalValue;
//Create a list of coins to store unlimited number of coins
// A pocket can half 5 dimes
List coins;
public Pocket(){
//Set initial value to zero
totalValue = 0;
currentValue = 0;
coins = new ArrayList<Coin>();
}
/**
* This method will take only one coin at a time
**/
public void addCoin(String s){
Coin c = new Coin(s);
coins.add(c);
totalValue+=c.getValue();
}
/**
* This method will take any number of coins of same type
**/
public void addCoin(String s, int c){
//Add each one to array
for(int i=0;i<c;i++)[
addCoin(s);
}
}
}
I am not in favor of keeping multiple coin values in one Coin object because of the fact it is not a true representation of an object. What does that mean is tomorrow if you want to store other Coin attributes like "Printed Year", "President Picture on the coin" etc, you will have hard time. In my opinion it is better to represent one real world object (one coin here) using one object instance in the program,

How do I pull value from method designated with "this."

I have information like this:
xxx 0 1 2 ...
Name Fred0 Fred1 Fred2
Stamina 2 6 7
Intel 5 4 1
Heart 4 8 2
Speed 5 3 6
So, I was informed previously that creating a 2D ArrayList to store something like this is "archaic" and was provided with a different way to set my code up. The reason I was using ArrayList<> is because I want to be able to generate new racers as needed, rather than designating an array to a size. If I could just use a simple array this would have been done a week ago. Now I've been screwing with it for a week and I still don't get how it works.
public class test {
public String name;
private int stamina;
private int heart;
private int intel;
private int speed;
public ArrayList<String> racers = new ArrayList<String>();
private void racerInfo(String name) {
this.name = name;
this.stamina = (int) Math.floor(Math.random()*10);
this.heart = (int) Math.floor(Math.random()*10);
this.intel = (int) Math.floor(Math.random()*10);
this.speed = (int) Math.floor(Math.random()*10);
}
public void generate() {
for ( int i=0; i<=10; i++) {
String name = "Fred" + i;
System.out.println(name);
racerInfo(name);
racers.add(name);
}
}
public int getStamina() {
return this.stamina;
}
public int getHeart() {
return this.heart;
}
public int getIntel() {
return this.intel;
}
public int getSpeed() {
return this.speed;
}
}
public class main {
public static test test = new test();
public static void main(String[] args) {
test.generate();
//Put stuff here to pull stamina of Fred2 for example.
}
}
Now, in the main class. How would I do something that should be relatively simple like pulling the Stamina value for Fred2.
I've been following the exact directions I've been given by others here to write most of this code. But at this time, I'm getting to the point of just re-writing it all so that each stat (name, stamina, intel, speed, etc.) is just logged as a separate ArrayList<>. But I can't figure out how to make a 2D ArrayList containing the original ArrayLists ie.
ArrayList<String> name = new ArrayList<String>();
ArrayList<Integer> stamina = new ArrayList<Integer>();
ArrayList<ArrayList<Object>> arrayOfArray = new ArrayList<ArrayList<Object>>();
Yes, I know the arrayOfArray is probably done wrong, but, again, I just get told it's Archaic and nobody'll tell me how I can do it right so I can just go. arrayOfArray.get(2,1) and pull information that I want/need.
Sorry for the information overload here. but I'm trying to just find the best possible solution for what I want to do. If you can tell me how to correctly pull off either way I will be eternally grateful you you and all of your descendants.
First of you should refactor your class test to class Racer, which is a meaningful name and follows the convention to start classnames with an uppercase letter. Furthermore you should add Stamina, Intel, Heart and Speed to the constructor:
public Racer(String name, int stamina, int intel, int heart, int speed) {
this.name = name;
this.stamina = stamina;
this.intel = intel;
this.heart = heart;
this.speed = speed;
}
Now you can create your racer as following:
Racer fred2 = new Racer("Fred2", 7, 1, 2, 6);
You can store your values in a HashMap. HashMap is a collection consisting of key-value pairs. For the key you can use a string (the name of the racer) and as value you take an instance of your class Racer:
HashMap<String, Racer>() racerMap = new HashMap<>();
racerMap.put("Fred2", fred2);
This you can do in a for-loop for all of your racers. Now you can get the racer objects from your HashMap by calling the getMethod and putting the name as parameter in it. This will return an object of class Racer and you can call the getter methods on this object:
racerMap.get("Fred2").getSpeed();
or
racerMap.get("Fred2").getIntel();
Edit: I just saw your generate method. This method should return the HashMap of racers. In your main method you create a new HashMap:
HashMap<String, Racer> racerMap = generate();
Now you can use the map as described above.

Categories