I am learning Java, so I understand this is a very simple question, but I still want to understand it.
I want to let my code automatically generate soldiers, and the number automatically increases, but I failed.
the Soldier.class:
package com.mayer;
import java.util.Random;
public class Soldier {
private int number=0;
private int ATK;
private int HP;
Random ra = new Random();
public Soldier(){
this.number++;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
public void report(){
System.out.println("number:"+this.number+"\t"+
"ATK:"+this.ATK+"\t"+
"HP:"+this.HP);
}
}
the main.class
package com.mayer;
public class Main {
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier();
i++;
}
for(Soldier sol:soldiers){
sol.report();
}
}
}
That's what I get:
number:1 ATK:94 HP:187
number:1 ATK:94 HP:181
number:1 ATK:96 HP:193
number:1 ATK:90 HP:183
number:1 ATK:95 HP:193
So you see,each of this number is 1.
You have added number field which is instance field. It will initialize per instance. You are looking for static type variable. Please check static into java.
Instance Variables (Non-Static Fields) Technically speaking, objects
store their individual states in "non-static fields", that is, fields
declared without the static keyword. Non-static fields are also known
as instance variables because their values are unique to each instance
of a class (to each object, in other words); the currentSpeed of one
bicycle is independent from the currentSpeed of another.
Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there
is exactly one copy of this variable in existence, regardless of how
many times the class has been instantiated. A field defining the
number of gears for a particular kind of bicycle could be marked as
static since conceptually the same number of gears will apply to all
instances. The code static int numGears = 6; would create such a
static field. Additionally, the keyword final could be added to
indicate that the number of gears will never change.
The constructor is changed to:
public Soldier(int number){
this.number = number;
this.ATK = ra.nextInt(10)+90;
this.HP = ra.nextInt(20)+180;
}
As others have said, each Soldier instance has its own separate number field which starts with 0. You can use a static field to count the instances:
public class Soldier {
private static int counter = 0;
private int number;
// other fields left out for clarity
public Soldier(){
Soldier.counter++; // field shared among all Soldier instances
this.number = counter; // number belongs to this instance only
// ...
}
// ...
}
However, I wouldn't recommend doing it this way. When you get more advanced, you'll learn that using a static field like this can cause problems in a multi-threaded application. I would instead advise passing the number to the Soldier constructor:
public class Soldier {
private int number;
// ...
public Soldier(int number){
this.number = number;
// ...
}
// ...
}
And then:
public static void main(String[] args) {
Soldier[] soldiers = new Soldier[5];
int i = 0;
while(i<5){
soldiers[i] = new Soldier(i);
i++;
}
Soldier.class
all-uppercase field names tend to be used for constants.. basic fields use headless camel-case.. They should also be descriptive, i.e. you should look at them an it should be apparent what they represent - for example a variable "number" is not a good idea, because it's ambiguous
Random can be converted to a local variable, no need to keep it on the class level
The mechanism by which soldiers are assigned IDs should be on a higher level - it can't be managed by the soldier object itself, hence the constructor with an argument
overriding the toString method is the traditional way of transforming the object to string for debugging purposes.. also most IDEs can generate it with a press of a button so no space for human error
You will obviously need getters and setters for your variables, if you wish to read or change them from elsewhere, but I don't think that's necessary to post here.
private int soldierID;
private int attack;
private int health;
public Soldier(int id){
this.soldierID = id;
Random random = new Random();
this.attack = random.nextInt(10) + 90;
this.health = random.nextInt(20) + 180;
}
#Override
public String toString() {
return "Soldier{" +
"soldierID=" + soldierID +
", attack=" + attack +
", health=" + health +
'}';
}
Main.class
it's perfectly fine and actually preferred to use a List instead of an array, because it's more comfortable to work with
this way it's even much easier to add them dynamically and use the iterator for ID
you can "report" in the creation cycle
This even shortens the method a bit, not that it's that important here.
public static void main(String[] args){
List<Soldier> soldiers = new ArrayList<>();
for(int i=0; i<5; i++){
Soldier newSoldier = new Soldier(i);
soldiers.add(newSoldier);
System.out.println(newSoldier.toString());
}
}
This way when you define the soldier IDs it's not from within the Soldier class but rather from something that is "observing" all the soldier classes and knows which is which.
Related
General part first:
This is for my Java 1 final: I need to make an NFL playoff simulator. So, I would make a "Team" object that holds values for "Offense" and whatnot. I would need a method that holds an algorithm to calculate who wins each matchup. However, I don't know how to go about applying the method to the appropriate teams..
I was going to make another object called "Matchup" which would hold 2 "Team" objects, then comparing the 2 teams' values with the algorithm method. But, I don't think you can use objects inside another object, to my knowledge... Therefore, I've just been trying to hard-code everything in an ugly way.
Would anyone point me in the right direction of forming such a program?
Anyway, on to my immediate issue:
Here is my small bit of code thus far..
public class Final_Larrabee {
static Team pit = new Team("Steelers", "AFC", 3, 75, 70);
static Team bal = new Team("Ravens", "AFC", 6, 70, 80);
static String teamA1 = "bal";
public static void main(String[] args) {
System.out.println(+teamA1.seed);
}
}
And my other class:
package final_larrabee;
public class Team {
String name;
String conference;
int seed;
int offense;
int defense;
boolean wcWin;
boolean divWin;
boolean conWin;
boolean alive;
public Team(String n, String c, int s, int o, int d) {
name = n;
conference = c;
seed = s;
offense = o;
defense = d;
wcWin = false; // these wins will be used in the betting part
divWin = false;
conWin = false;
alive = true; // determines if team is out of playoffs or not
}
public String getName(){
return this.name;
}
public void setName(String n){
name = n;
}
public int getConference(){
return this.seed;
}
public void setConference(String c){
conference = c;
}
public int getSeed(){
return this.seed;
}
public void setSeed(int s){
seed = s;
}
public int getOffense(){
return this.offense;
}
public void setOffense(int o){
offense = o;
}
public int getDefense(){
return this.defense;
}
public void setDefense(int d){
defense = d;
}
}
I realize this won't work, because it is trying to access teanA1's seed value (which doesn't exist of course). But, what I wanted was to simply call the bal.seed value. I wanted to do it this way so that later, I can use teamA1 and teamA2 variables for the 2 teams in a given matchup. Is there a way to do it this way?
If not, perhaps ideally, it would be best to create a Team object called teamA1 which holds the values of whatever team I need at the time. It would need to change like a variable instead of make a million objects every time I need it (ideally..) I found the method 'clone' but I'm not sure this is what I want?
Any help, be it to my immediate question, or the general layout of my program, would be much appreciated. Thanks!
make team implements comparable this will give you the ability to write compareTo method and then you can put you win condition based
Just as your class Final_Larrabee holds 2 team objects in your code, your matchup class can also hold other objects.
Yes, you're on the right track with the idea of creating a matchup class which holds instances of team objects.
Inside your main class you can initialize 2 team objects. I would then create a matchup object, which gets passed the 2 team objects you have previously created and do some functionality.
Inside your team class you could implement a method, which returns a score based on the teams stats. For example it could calculate the offense * defence * seed or something like and return it that and then inside your match class, you can then implement a method such as playGame() which calls the getScore() method of each object and compares the values and then returns the winner (or prints them out for simplicity).
As regards your code, you're using the keyword static. Static is a keyword which changes a variable/object/method to a class variable/object/method. This means that every instance of the class shares this variable. I would not use it for creating the teams. An example of where to use static (a very basic example), would be if for some reason you needed to keep track of the amount of team objects you created. You could implement a static COUNT variable inside the team object and increase it by one every time the constructor is called. This could also be used for assigning IDs to the teams.
static int TEAM_COUNT = 0;
public Team()
{
this.id = ++TEAM_COUNT;
}
This would make the TEAM_COUNT be a value which shared by all instances of the class team. If you were to call
teamA.setTeamCount(0);
Then every other instance of Team would also be reset to 0.
Edit: With regards to your playoffs
public static void main(String args[])
{
Team team1 = new Team("parameters required here");
Team team2 = new Team("parameters required here");
Playoff p = new Playoff();
p.add(team1);
p.add(team2);
p.startPlayoffs();
}
If you create all of the objects inside the main class, then they are available to that method as they are local. When you call p.add(), you can add them to an array or collection, which is inside the Playoff class. Your startPlayoffs() method can then process the array of objects already stored inside the class.
I'm working on a little project for fun, that's essentially a little combat emulator. I'm trying to use a class similar to struct in C++, as in using it to create an object (in this case, a character or "entity", as the class is called). I'm getting the error in the title when attempting to call any integer in said class from the main function.
class entity{
public int health;
public int accuracy;
public int power;
public int defense;
}
And
public class Tutorial {
static Random rnd = new Random();
entity player;
player.health = 100; // Issue on the health part
player.accuracy = 19; // Issue on the accuracy part
player.power = 15; // Issue on the power part
player.defense = 18; // I think you get it by now...
I've been looking around for a while to find some explanation, but there's none that I could find that explain the nature of the error as well as possible fixes for my situation. If I could get those, it would be wonderful.
The compiler is expecting a variable declaration on the line
player.health = 100;
but is finding an assignment instead. The statements
Entity player = new Entity();
player.health = 100;
player.accuracy = 19;
player.power = 15;
player.defense = 18;
should be in a code block such as a method or constructor rather than the class block
Procedural code cannot be written directly in a class definition. The code is causing syntax errors because it's not legal to do so.
Instead, put the code in an appropriate method or initialization block. (I do not think an initialization block is appropriate here, so I am trivially showing a "factory method".)
As such, consider an approach like
// This is a member variable declaration, which is why it's OK
// to have a (static) method call provide the value.
// Alternatively, player could also be initialized in the constructor.
Entity player = makeMeAPlayer();
static Entity makeMeAPlayer() {
// Create and return entity; the code is inside a method
Entity player = new Entity();
player.health = 100;
// etc.
return player;
}
(I've also cleaned up the type to match Java Naming Conventions - follow suite!)
Here is another way to suffer from highly accurate yet not terrible intuitive messaging for VariableDeclaratorId.
#PostMapping("/showCompany")
public String processForm(#ModelAttribute("company") CompaniesDAO company, company_name, company_function) {
Will produce:
Syntax error, insert "... VariableDeclaratorId" to complete FormalParameter
This is telling you that is need the variable type like String or int...
#PostMapping("/showCompany")
public String processForm(#ModelAttribute("company") CompaniesDAO company, String company_name, String company_function) {
It turns out VariableDeclaratorId is a class
public class VariableDeclaratorId
extends Expression
implements prettyprint.PrettyPrintable
If you read the class description using it with the error message to determine that you forgot to define the variable type, I am impressed; I simply made an educated guess.
It is because you forgot to add the main method,
public class Tutorial {
public static void main(String[] args) {
static Random rnd = new Random();
entity player;
player.health = 100; // Issue on the health part
player.accuracy = 19; // Issue on the accuracy part
player.power = 15; // Issue on the power part
player.defense = 18; // I think you get it by now...
}
}
and
class entity{
public int health;
public int accuracy;
public int power;
public int defense;
}
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 9 years ago.
I've read the Oracle documents regarding scope and controlling access yet it just isn't sticking, so I'm assuming that my issue comes from my failure to understand... Anyways Here's my code. I'm trying to access the unique Player objects created in an array, and change their unique variables like their balances, using methods from the Player class. Any solutions and ESPECIALLY explanations are welcome!
public class Player
{
private int currentBal;
private String myName;
private int rollOne;
private int rollTwo;
private int rollTotal;
private int doublesCount;
private int currentPosition;
private int currentDoubles;
private int move;
private int moveMult;
private int newBal;
private boolean rollAgain;
private boolean inJail;
public Player(String userName, int changeInMoney)
{
myName = userName;
currentBal -= changeBalance(changeInMoney);
}
public int changeBalance(int changeInMoney){newBal -= changeInMoney; return newBal;}
public int viewBalance(){return currentBal;}
Here is my PlayerArray class.
public class PlayerArray
{
Scanner scan = new Scanner(System.in);
private int numbHuman;
private Player[] arr;
private String[] userName;
private int startingMoney;
public PlayerArray()
{
Scanner scan = new Scanner(System.in);
System.out.println("There will be 4 players, how many do you wish to be human? 0><4");
numbHuman = scan.nextInt();
while (numbHuman < 1 || numbHuman > 4)
{
System.out.println("Invalid entry, try again.");
numbHuman = scan.nextInt();
}
arr = new Player[numbHuman];
userName = new String[numbHuman];
startingMoney = 1500;
for(int i = 0; i < arr.length; i++)
{
System.out.println("Player " + (i + 1) + ", Please enter your first name:");
userName[i] = scan.next();
arr[i] = new Player(userName[i],startingMoney);
}
}
public Player[] getPlayerArray()
{
int charge = 500;
arr[0].changeBalance(charge);
System.out.println(arr[0].viewBalance()); //look here as example
return arr;
}
}
this is my player class, minus some methods I can't use till later. Bellow is my main method to call it,
import java.util.Scanner;
import java.util.Random;
public class Launcher
{
private Planet myTest;
private PlanetInfo myPlanetInfo;
private static Player[] arr;
public static void main(String[] args)
{
Launcher testLauncher = new Launcher();
PlayerArray myArray = new PlayerArray();
Pay myCharge = new Pay(); // continue work on charges
myArray.getPlayerArray();
//STILL TRYING TO GET BELLOW LINE TO WORK LAST NIGHT!!!
int testBal = arr[0].viewBalance(); //ERROR HERE
System.out.println("player 1's balance: " + testBal);
}
}
Error "Java.lang.NullPointerException: null"
Your main method is a static method. It actually exists before any object is created from your class, and thus cannot access instance variables and methods directly. You cannot access non static methods or variables from the same class unless you create an object for the class, i.e Launcher launcher = new Launcher();.
In this case, your player array arr is not static. You either need to make this static or create a Launcher object and access the variable from there. In the latter case, you will need to make the arr array public.
The first option requires you to change your player array declaration to private static Player arr;.
The second requires you to change the access of the arr array to public and access it like so: launcher.arr.
Regarding your second error, you need to either do this: arr = myArray.getPlayerArray();
or just access the array directly like this: myArray.getPlayerArray()[0] (for the first item in that array).
Variable 'Player[] arr' is instance variable, i.e. it should belongs to particular instance. Static method 'main' can't directly access an instance variable from the class it's in, because it doesn't have an explicit reference to any particular instance of the class (simply said at this point, you don't have an instance to whom your Player[] arr belongs).
Make your variables static, since main is a static method, you can't reference non-static methods.
so make your variables on top something like:
private static Player[] arr;
Since your Launcher has no instance none of its non static members exist. Static method main cannot access such - in this case your arr does not exist. You may want to make it static to make it work.
Read static and instance members
I have a task to operate on complex number. Each number consists of double r = real part, double i = imaginary part and String name. Name must be set within constructor, so I've created int counter, then I'm sending its value to setNextName function and get name letter back. Unfortunately incrementing this 'counter' value works only within costructor and then it is once again set to 0. How to deal with that?Some constant value? And second problem is that I also need to provide setNextNames(char c) function that will change the counter current value.
The code :
public class Imaginary {
private double re;
private double im;
private String real;
private String imaginary;
private String name;
private int counter=0;
public Imaginary(double r, double u){
re = r;
im = u;
name = this.setNextName(counter);
counter++;
}
public static String setNextName(int c){
String nameTab[] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","W","V","X","Y","Z"};
String setName = nameTab[c];
System.out.println("c: "+c);
return setName;
}
public static String setNextName(char c){
//
//don't know how to deal with this part
//
}
It's hard to tell what you're doing, but I suspect this will solve your immediate problem:
private static int counter = 0;
You should make counter static.
You should also make nameTab a private static field, then in setNextName(), you can iterate through it to find the name corresponding to the given character, and get its index. (in the plain ASCII world, of course one could simply calculate the index by subtracting the numeric value of 'A' from the given character, but I am not quite sure how it would work out with Java, in Unicode, with crazy inputs - iteration is on the safe side.)
In OO languages there are typically two types of variables that go into a class:
instance variables that are unique to each instance
class variables that are shared by all instances of the class
Given a class like:
public class Person
{
// class variable
private static int numberOfEyes;
// instance variable
private String name;
// other code goes here
}
If you were to do something like:
Person a = new Person("Jane Doe");
Person b = new Person("John Doe");
and then do something like:
a.setName("Jane Foe");
the name for Person "a" would change, but the one for Person "b" would stay the same.
If you woke up one morning and decided you wanted 3 eyes:
Person.setNumberOfEyes(3);
then Person "a" and Person "b" and every other Person instance out there would suddenly have 3 eyes as well.
You want to put "static" in your counter declaration.
is your code being used by multiple threads than i would suggest that making counter static won't solve ur problem.
you need to take extra care by implementing thread synchronization use lock keyword as shown below.
private static readonly obj = new Object();
private static int counter =0;
public Imaginary(double r, double u)
{
re = r;
im = u;
lock(obj)
{
name = this.setNextName(counter);
counter++;
}
}
this will ensure thread safety also while incrementing your counter (there are another ways also to provide thread security but this one is having least code).
Because the field counter is not static, every object has its own counter.
Say I wanted to make a class to hold a set of integers that would be accessed from multiple other classes and instances. I don't want them reverting to the value they had when the code was compiled. Does that mean they have to be static, in order to keep them from going back their original value? For example
The original stats holding class here:
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
It is called on in two places. Here:
public class exampleClass() {
private Stats stats = new Stats();
stats.numOne += 5;
//More variable changes.
}
Also here:
public class exampleClassTwo() {
private Stats stats = new Stats();
stats.numOne -= 3;
//More variable changes.
}
Will these calls reset the variables to their original class value if the variables are not static? If so, does that mean they should always be static?
No, the variables will maintain state without the static modifier
No. You would use static key word for using those values without initializating them.
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
public class exampleClass() {
int a = 0;
a += Stats.numThree;
System.out.println(a);
}
>>> 3;
No need for static attributes in your case indeed, each class instance will contain a private copy of attributes initialized at instance creation time, and records all subsequent modifications until object is deleted (in java it means no longer referenced).
Main usage for static is either to store constants or global state (e.g. a singleton instance).
Doing,
private Stats stats = new Stats();
stats.numOne += 5;
Kind of defeats the purpose of having numOne as static.
The static field numOne should be accessed in a static way i.e as follows: Stats.numOne
static variables are Class variables and are used when we want to maintain a value across instances of the class. So modifying the value of numOne across various functions will keep on changing the value of class variable numOne. Run the following code to see the effect of having a class variable in a class:
public class StaticVarDemo {
public static int staticCount =0 ;
public StaticVarDemo(){
staticCount++;
}
public static void main(String[] args) {
new StaticVarDemo();
StaticVarDemo.staticCount +=5;
System.out.println("staticCount : " + StaticVarDemo.staticCount);
new StaticVarDemo();
new StaticVarDemo();
System.out.println("staticCount : "+staticCount);
}
}
It will give the output:
staticCount : 6
staticCount : 8
Yes, when you instantiate an object, variables will be initialized to the class values when they are not static.
When a variable has the static keyword, that variable value persists over all instances: the two places you called it each create an object, both objects have the same values for their static variables (even if they are changed).
Variables without the static keyword are unique to the instance: changing it on one object doesn't affect its value on the other.
See here for more info:
What does the 'static' keyword do in a class?
It seems after some research a singleton did the job. Creating one singular instance but calling on it more then once.
See Here:
http://www.tutorialspoint.com/java/java_using_singleton.htm