Java: Array of Objects overwritten by last element [duplicate] - java

I have the following code:
public static void main(String[] args) {
Player players[] = new Player[2];
Scanner kb = new Scanner(System.in);
System.out.println("Enter Player 1's name");
players[0] = new Player(kb.nextLine());
System.out.println("Enter Player 2's name");
players[1] = new Player(kb.nextLine());
System.out.println("Welcome "+ players[0].getName() + " and " + players[1].getName());
}
It is meant to create a new player object and store the name of the player, while keeping all the objects in the array.
Here is the player class:
public class Player {
static String name;
public Player(String playerName) {
name = playerName;
}
public String getName(){
return name;
}
}
What actually happens is that it works when I just have 1 object, but when I have 2, each element in the array is the same as the second. When I have 3 objects in the array, each element is the same as the 3rd, etc.
I'm not sure why this is happening, or how to correct it, and it's been baffling me for hours :/

Its because of the static field. Statics are used across object instances. They are stored at class level.
Below code would work:
class Player
{
String name;
public Player(String playerName)
{
name = playerName;
}
public String getName()
{
return name;
}
}

Change static string name to private string name

Name field should not be static. Static means that the variable is actually global and shared across all class instances.

With the keyword static you have made name a class variable which is NOT an instance variable. A class variable is common to all the objects. Click for some more reading.

Related

Cannot make a static reference to the non-static field players

I'm making a program in java to register players and add them in an arraylist. My method for adding players is this:
void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
my problem is that i don't know where to put
ArrayList<Player> players = new ArrayList<>();
if i have it in main, the method doesn't know what players is, but if i have it in the class i get a "Cannot make a static reference to the non-static field players" exception, when i try to print it from main. What's the best way of solving this.
Update: thanks for the help, i realized that since my command loop is already running on an instanced version of my class there is actually no problem, there was only a problem when i tried to test my method outside the instanced command loop.
If you'd like to have it at the class level, escape the static context.
public class YourClass {
ArrayList<Player> players = new ArrayList<>();
public static void main(String[] args) {
new YourClass(); // or YourClass yourClass = new YourClass();
}
// Create an instance of YourClass to leave the static context
public YourClass() {
registerNewPlayer();
}
public void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
System.out.print("Weight?> ");
int weight = input.nextInt();
Player player = new Player(name, game, age, weight);
players.add(player);
}
}
I thinik this is the best solution for your problem. I hope it helps :)
Your Player class:
public class Player {
private static ArrayList<Player> _players = new ArrayList<Player>();
private String name;
private String game;
private int age;
private int weight;
public Player(String name, String game, int age, int weight){
this.name = name;
this.game = game;
this.age = age;
this.weight = weight;
}
public static void AddPlayer(Player player){
_players.add(player);
}
public static ArrayList<Player> getPlayers(){
return _players;
}
}
Now you can create some players and get them as follow:
... main ...
.
.
.
Player p1 = new Player("Name1", "Game1", 20, 70);
Player p2 = new Player("Name2", "Game2", 30, 80);
Player p3 = new Player("Name2", "Game3", 25, 73);
Player.AddPlayer(p1);
Player.AddPlayer(p2);
Player.AddPlayer(p3);
ArrayList<Player> allPlayers = Player.getPlayers();
.
.
.
Let me know if it is working for you !
The error you get is because you are trying to access a non-static variable (i.e. a value or object that exists only in instances of that class) from outside of such an instance. What you can do is to create an object of that class to be able to access the players through it:
public class Demo {
private List<Player> players = new ArrayList<>();
public static void main(String[] args) {
Demo demo = new Demo();
demo.registerNewPlayer();
System.out.println(demo.players);
}
private void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
}
By creating an object of the class and executing the method as well as access the variable through it, allows you to do what you want (if I understood correctly that is).
Further reading material:
Java: when to use static methods
Type List vs type ArrayList in Java (you may have noticed that I changed the type of players to List<Player> from ArrayList<Player>)
What is the difference between public, protected, package-private and private in Java? (you may have noticed the private keyword on the list and the method)
Globally declare the list.
ArrayList<Player> players = new ArrayList<>();

Illegal Self Reference in creation of class

I am pretty new to Java, my code is giving me the error "Illegal Self reference" in the lines below on Charmander/Squirtle/Bulbasaur.moveList
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
Here is my code
public class Pokemon_Builder {
public static void main(String[] args) {
Move_Builder mb = new Move_Builder();
Charmander.moveList.add(mb.Ember);
Charmander.moveList.add(mb.Scratch);
Charmander.moveList.add(mb.Willowisp);
Charmander.moveList.add(mb.Recover);
Squirtle.moveList.add(mb.Bubble);
Squirtle.moveList.add(mb.Tackle);
Squirtle.moveList.add(mb.Powdersnow);
Squirtle.moveList.add(mb.Recover);
Bulbasaur.moveList.add(mb.Vinewhip);
Bulbasaur.moveList.add(mb.Poisonpowder);
Bulbasaur.moveList.add(mb.Tackle);
Bulbasaur.moveList.add(mb.Recover);
System.out.println(Charmander.moveList.size());
}
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
}
And here is the code for the Pokemon Class:
import java.util.LinkedList;
import java.util.List;
public class Pokemon{
String type;
String name;
int health;
List<Move> moveList = new LinkedList<Move>();
public Pokemon(String type, String name, int health, LinkedList moveList) {
this.type = type;
this.name = name;
this.health = health;
this.moveList = moveList;
}
public void getInfo (){
System.out.println("Pokemon Name "+ this.name);
System.out.println("Your Pokemon's type "+ this.type);
System.out.println("Your Pokemon's health "+ this.health);
}
public void addMove(Move toAdd){
if (moveList.size() < 5){
moveList.add(toAdd);
}
else{System.out.println("Can't learn any more moves!");
}
}
}
Thanks in advance for the help
In your class Pokemon_builder you create 3 pokemon, while creating those pokemon you provide a moveList. Those movelists are created when the pokemon is created. Meaning what you now try to do is pass a field of a pokemon to the constructor for that pokemon.
As your Pokemon object is instantiating itself the the static member object creation runs before the constructors do. You are trying to create an object called Charmander and pass into Charmander's constructor a reference to a static "movelist" object within Charmander. You are doing this BEFORE Charmander has completed its object instantiation process. Thus you are trying to create an object that needs a reference within itself to "construct" itself.

How do I create an object from another class (BlueJ)

I am making a program that simulates a Store and a Member. I am trying to write a method, memberRegister2(). This method is the the Store class but calls the constructor from the Member class to make a member object. This method is to be passed the name, id and pinNumber as parameters and then creates the Member object, which is to be stored in a local variable 'member'. I have no idea how to do this. As you will see from the code below I have tried to use the 'Member member = new Member()' But i do not know how to make the parameters user input.
(P.S I am using BlueJ)
Here is my code for both classes hopefully making my question make more sense. I am very new to java so excuse bad coding.
public class Store
{
// instance variables
private String storeName;
private int total;
//Member member;
/**
* Constructor for objects of class Store
*/
public Store(String newStoreName, int newTotal)
{
// initialise instance variables
storeName = newStoreName;
total = newTotal;
}
//Accessor Methods
public String getStoreName()
{
return storeName;
}
public int getTotal()
{
return total;
}
public void memberRegister1(Member newMember)
{
System.out.println("Salford Thrifty " + storeName + ": Welcome " + newMember.getName() + " (id:" + newMember.getId() + ")" );
}
public void memberRegister2()
{
//Member member = new member(memberName, memberId, memberPinNumber);
}
//Mutator Methods
public void newStoreName(String newName)
{
storeName = newName;
}
public void newTotal(int newTotal)
{
total = newTotal;
}
}
and the Member class
public class Member
{
// instance variables
private String name;
private String id;
private String pinNumber;
/**
* Constructor for objects of class Member
*/
public Member(String memberName, String memberId, String memberPinNumber)
{
// initialise instance variables
name = memberName;
id = memberId;
pinNumber = memberPinNumber;
}
public Member()
{
// initialise instance variables
name = "Bob";
id = "ASD123";
pinNumber = "5678";
}
//Accessor Methods
public String getName()
{
return name;
}
public String getId()
{
return id;
}
public String getPinNumber()
{
return pinNumber;
}
//Mutator Methods
public void newName(String newMemberName)
{
name = newMemberName;
}
public void newId(String newMemberId)
{
name = newMemberId;
}
public void newPinNumber(String newMemberPinNumber)
{
name = newMemberPinNumber;
}
}
I have been told to keep the variable at the top private and use pointers? Not sure what this means but it has not been explained to me very well.
You can a Scanner to read the user's input like so.
Scanner s = new Scanner(System.in);
String userInput = s.nextLine();
Then just initialize your member instance using the strings entered by the user.
String memberName, memberId, memberPin;
Scanner s = new Scanner(System.in);
System.out.println("Enter a name");
memberName = s.nextLine();
System.out.println("Enter an id");
memberId = s.nextLine();
System.out.println("Enter a pin");
memberPin = s.nextLine();
Member m = new Member(memberName, memberId, memberPin);
Also, you probably want to make pin, and maybe the id ints instead of strings.
Here's something I have from an old class that should show you how:
SavingsAccount myAccount = new SavingsAccount(200, 5);
So when you want to create an object from another class you have to use that second class to initialize it as shown above the SavingsAccount is like int it instantiates the object and then the two integers SavingsAccount(200, 5); is used because the method within the second class is instantiated with two integers of its own so the object you are creating must have two integers of its own. And what I mean by the method has two integer instantiated is as shown in the code below:
public SavingsAccount(double amount, double rate)
{
super(amount);
interestRate = rate;
}
if you do not instantiate a method with two objects within the parentheses then you do not need them within:
SavingsAccount myAccount = new SavingsAccount(200, 5);
I hope this helps any with your question i'm fairly new myself and am trying to help with as much as I can My course uses BlueJ as well and I know a good bit about BlueJ so I hope this helps.

Is there a way to create an object with object name from the value of a string

class states{
List<String> cities = new ArrayList<String>();
public void add_city(String current_city){
this.cities.add(current_city);
}
}
class add_values{
public static void main(String [] args){
System.out.println("Enter the state name : ");
Scanner sc = new Scanner(System.in);
String user_state = sc.nextLine(); // need to create an object with the name from a string value
states user_state = new states();
....
....
}
}
Is there a way to create an object for a class with the name from a string.
If, user enters the state name as "Michigan", an object is created with "Michigan" which is got from scanner. and cities can be added for the state Michigan.
You will want to understand that objects have no names -- none, zero, zip. Yes, variables can have names, but that is not the same, since two or more variables can refer to the same object, and when that happens, which name is the name for the object? Again, neither/none since objects don't have names. As for variable names, they're way less important than you believe and almost don't exist in compiled code. What is most important are object references. Here an object can be associated with a String by means of a Map such as a HashMap<String, String> which is similar to an array or ArrayList that uses a String as its index rather than a number.
Now having said this, you can give your State class a String name field, and this may serve your purposes well.
i.e.,
import java.util.ArrayList;
import java.util.List;
public class State {
private String name;
private List<String> cities = new ArrayList<>();
public State(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addCity(String city) {
cities.add(city);
}
public List<String> getCities() {
return cities;
}
#Override
public String toString() {
return "State of " + name + ", Cities: " + cities;
}
}
Which can be run like:
public class StateTest {
public static void main(String[] args) {
State illinois = new State("Illinois");
illinois.addCity("Chicago");
illinois.addCity("Peoria");
illinois.addCity("Springfield");
System.out.println(illinois);
}
}
You can do something different using HashMap. Hope this will help to achieve your goal. Here is the code:
class States{
List<String> cities = new ArrayList<String>();
public void add_city(String current_city){
this.cities.add(current_city);
}
}
class add_values{
public static void main(String [] args){
HashMap<String, States> userStatesMap = new HashMap<String, States>();
System.out.println("Enter the state name : ");
Scanner sc = new Scanner(System.in);
String user_state = sc.nextLine(); // need to create an object with the name from a string value
userStatesMap.put(user_state, new states());
....
....
}
}

Adding new objects to an ArrayList in constructor

I am trying to add newly created objects to an ArrayList in the constructor of a class. The new objects are being created in another class in the main method.
Main method:
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
My Player class:
public class Player {
protected static int age;
protected static String name;
protected static ArrayList players = new ArrayList();
Player(String aName) {
name = aName;
age = 15;
players.add(new Player()); // i know this doesn't work but trying along these lines
}
}
You have to edit the line
players.add(new Player());
to
players.add(this);
Also, there is no need to make the age and name static
I suggest you should have the following code instead
import java.util.ArrayList;
public class Player {
protected int age; //static is removed
protected String name; // static is removed
protected static ArrayList<Player> players = new ArrayList<Player>(); //this is not a best practice to have a list of player inside player.
Player(String aName) {
name = aName;
age = 15;
players.add(this); // i know this doesn't work but trying along these lines
}
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
}
It sounds like you're actually asking how to refer to the instance you're constructing.
That's what the this keyword does.
This post is old, but for someone with similiar needs I suggest doing it like this:
Main class:
public static void main(String[] args) {
//TODO code application logic here
java.util.List<Player> players = new java.util.ArrayList<>(); //list to hold all players
Player p1 = new Player("Peter"); //test player
players.add(p1); //adding test player to the list
players.add(new Player("Peter")); //also possible in this case to add test player without creating variable for it.
}
Player class:
public class Player {
private final int age = 15; //if you always going to use 15 as a age like in your case it could be final. if not then pass it to constructor and initialize the same way as the name.
private String name;
Player(String name) { //variable name can be the same as one in class, just add this prefix to indicated you are talking about the one which is global class variable.
this.name = name;
}
}
Generally you should avoid using static keyword on variables which supposed to be different in each instance of that class. Avoid having object of itself inside.

Categories