Java global variables not updating in new class - java

I am currently programming a simple Android app that asks the user a series of questions and then tells them how many they got correct. I have one class that has a global variable (called "score") that is private and I have getter and setter methods for it. When the user gets the answer correct, the score is incremented (locally) and updates from 0 to 1 in that class. However, when I try to use the getScore() method I have created, to access the value of score in another class, it says scores value is 0, and not 1.
E.g.
public ClassA {
private int score = 0;
public void setScore(int s) {
this.score = s;
}
public int getScore() {
return score;
}
}
public ClassB {
private ClassA eg = new ClassA();
private int score = eg.getScore();
}
I've been stuck on this for a while and really don't know why this isn't working.
Help is much appreciated.
Thanks.

Set the Score, before getting the Score.
public ClassB {
private ClassA eg = new ClassA();
eg.setScore(5);
private int score = eg.getScore();
System.out.println(score);
}
Hope this helps.

Make sure to actually increment the score in ClassB. Also make score a static variable.

Edit your code like this :
public ClassA {
private static int score = 0;
public void setScore(int s) {
this.score = s;
}
public int getScore() {
return score;
}
}
public ClassB {
private ClassA eg = new ClassA();
int score = 0;
if(answerCorrect())
{
score++;
eg.setScore(score);
}
private int realScore = eg.getScore();
System.out.print("Final Score : "+realScore);
}
And, create a method answerCorrect() to check whether answer is correct or not, this method will return boolean.

Related

Return enum into toString and accessor methods

As the code showed below, I'm trying to make user input the speed (1,2,3) into the enum and return the input back into toString method.
private enum speed
{
SMALL(1),
MEDIUM(2),
FAST(3);
private int speedValue;
private speed (int speedValue)
{
this.speedValue = speedValue;
}
public int getSpeed()
{
return speedValue;
}
public static Optional<speed> get(int speedValue)
{
return Arrays.stream(speed.values())
.filter(spe -> spe.speedValue == speedValue)
.findFirst();
}
}
private boolean on;
The problem is when I put this.speed = speed or any other stuff, the speed class will be missing with error "speed cannot be resolved or is not a field"
This happened the same in the toString class.
public Fan(speed seed, boolean on)
{
speed.get() = seed; //what shall i put here
this.on = on;
}
public boolean getOn()
{
return this.on;
}
public String toString()
{
return speed; //what shall i put here
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter speed");
int sp = sc.nextInt();
System.out.println("On/Off");
boolean on = sc.nextBoolean();
Optional<speed>spe = speed.get(sp); //getting enum integer values
System.out.println(spe.get());
Fan fan = new Fan(sp, on)
Is there any solution that I would be able to return the integer value of enum into the public class and toString class?
With private enum speed {...} you declare the enum type speed, but you never declare a field of this type.
If you want to have a field named speed of this enum type you must declare it with private speed speed;.
This looks confusing and therefore I suggest that you follow the Java naming conventions where names of classes start with an uppercase letter (and enum types are classes).
That means your enum type should be written as
public enum Speed {
SMALL(1),
MEDIUM(2),
FAST(3);
private int speedValue;
private Speed (int speedValue) {
this.speedValue = speedValue;
}
public int getSpeed() {
return speedValue;
}
public static Optional<Speed> get(int speedValue) {
return Arrays.stream(Speed.values())
.filter(spe -> spe.speedValue == speedValue)
.findFirst();
}
}
Your Fan class needs these fields:
private boolean on;
private Speed speed;
The constructor is
public Fan(Speed seed, boolean on) {
speed = seed;
this.on = on;
}
or, assuming that the parameter name seed is a spelling mistake and it should be speed instead:
public Fan(Speed speed, boolean on) {
this.speed = speed;
this.on = on;
}
The other methods:
public boolean getOn() {
return this.on;
}
public String toString() {
return speed.toString();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter speed");
int sp = sc.nextInt();
System.out.println("On/Off");
boolean on = sc.nextBoolean();
Optional<Speed> spe = Speed.get(sp); //getting enum integer values
System.out.println(spe.get());
Fan fan = new Fan(spe.get(), on);
// note that the above line produces not output. Why should it?
// if you want to see the result of f.toString() you need to print it out:
System.out.println(fan.toString());
// or shorter (since println() calls toString() automatically):
System.out.println(fan);
}
Note 1: I also changed the placement of the opening braces ({) to follow general Java conventions - for seasoned Java programmers this looks less surprising.
Note 2: as Mark Rotteveel correctly remarks: the Fan class has a public constructor and therefore the Speed enum should also be declared public. Otherwise no one outside of the Fan class will be able to construct a new Fan object.

Is it possible to call a constructor from a class to another, and perform mathematical operation, and return its results, in Java?

I would like to know if Java allows you to call a constructor from a different class, and perform mathematical operations on it. And return its results in the Main class.
For example, I have
public class Wallet {
private int dollar;
public Wallet(int dollar){
this.dollar = dollar;
}
I also have
public class Count {
private int counter;
private ArrayList<Wallet> wallet;
public Count(){
this.wallet = new ArrayList<Wallet>();
}
public void addWallets(Wallet dollar) {
this.wallet.add(dollar);
}
public int sum(){
return 0;}
Now, my goal is to add the amount of money in each wallet, and print the results. This is the main class.
public class Main {
public static void main(String[] args) {
Count count = new Count();
Wallet wallet1 = new Wallet(34);
Waller wallet2 = new Wallet(26);
count.addWallets(wallet1);
count.addWallets(wallet2);
System.out.println( "Total is: " + count.sum() );
}
}
Thank you for your help!
The question you asked is quite unclear. But I will try to help you.
goal is to add the amount of money in each wallet, and print the
results.
Have a getter and setter methods for dollar in your Wallet class. So that you can use them later in the program.
In sum method sum of the dollars from each Wallet.
Here is the solution:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
Count count = new Count();
Wallet wallet1 = new Wallet(34);
Wallet wallet2 = new Wallet(26);
count.addWallets(wallet1);
count.addWallets(wallet2);
System.out.println("Total is: " + count.sum());
}
}
class Count {
private int counter;
private ArrayList<Wallet> wallet;
public Count() {
this.wallet = new ArrayList<Wallet>();
}
public void addWallets(Wallet dollar) {
this.wallet.add(dollar);
}
public int sum() {
int sum = 0;
for(Wallet w : wallet) {
sum += w.getDollar();
}
return sum;
}
}
class Wallet {
private int dollar;
Wallet(int dollar){
this.dollar = dollar;
}
public int getDollar() {
return dollar;
}
public void setDollar(int dollar) {
this.dollar = dollar;
}
}
In sum() method you can create object of Wallet class like Wallet wt=new Wallet(10) it will internally call the constructor of Wallet but not possible to call explicitly.You can call in super class and same class using this and super keyword.
I think you misunderstood the working of a list.
When you are running below code,
count.addWallets(wallet1);
count.addWallets(wallet2);
It adds wallet1 and wallet2 to ArrayList<Wallet> wallet of count as two separate elements.
When you are callingcount.sum(), that method will always return 0 based on your method declaration. If you want to get the sum of all elements when you are calling that method, try declaring the method as below:
public int sum(){
int total =0;
for(int i=0;i< wallet.size();i++){
total = total + wallet.get(i).getDollar();
}
return total;
}
And add setters and getters in your Wallet class for Dollar as
public int getDollar() {
return dollar;
}
public void setDollar(int dollar) {
this.dollar = dollar;
}
That way when you call the method, it gets the sum of dollars in all wallets and returns you.

How to access variables in a different class?

My first class called Match creates an individual soccer/football game. It makes you choose 2 teams and the final score. The second class called "team" is a bit more advanced. When the play (match match) method is called, the number of games played increments by 1. This part works fine. My else if statements for (goalsForThisMatch) also works fine. However, when I inspect the Team class object, it should display the same goals for and goals against that I inputted in the Match class. What actually happens is when I inspect the Team class after pressing the play(Match match) method, most of the methods are set to 0, except the "played" method (which increments by 1 like it's supposed to) and whatever the final score is. So if I inputted the score in the match class so that the home team has scored more goals and has won the match, then the Won method in the object inspector for the Team class will go up by 1. I need two of the other methods in the team class to link with the match class. These methods are: Goals For and Goals Against. If I input the GoalsFor in the match class to be "4" then when I inspect the Team class the goalsFor should be set to 4 also.
I know this all probably sounds VERY confusing, please forgive me, I'm so TIRED I'm about to head off to sleep. Hopefully in the morning, someone would have sorted this issue for me.
public class Match
// instance variables - replace the example below with your own
private String HomeTeam;
private String AwayTeam;
private int HomeGoals;
private int AwayGoals;
/**
* Constructor for objects of class Match
*/
public Match(String ShortHomeTeamName, String ShortAwayTeamName, int NewHomeGoals, int NewAwayGoals)
{
// initialise instance variables
HomeTeam = ShortHomeTeamName;
AwayTeam = ShortAwayTeamName;
HomeGoals = NewHomeGoals;
AwayGoals = NewAwayGoals;
}
public String getHomeTeamName(){
return HomeTeam;
}
public String getAwayTeamName(){
return AwayTeam;
}
public int getHomeGoals(){
return HomeGoals;
}
public int getAwayGoals(){
return AwayGoals;
}
}
public class Team
private String TeamName;
private String ShortName;
private int Played;
private int GoalsFor;
private int GoalsAgainst;
private int GoalDifference;
private int Won;
private int Drawn;
private int Lost;
private int Points;
/**
* Constructor for objects of class Team
*/
public Team(String FullTeamName, String ShortTeamName)
{
// initialise instance variables
TeamName = FullTeamName;
ShortName = ShortTeamName;
Played = 0;
GoalsFor = 0;
GoalsAgainst = 0;
GoalDifference = 0;
Won = 0;
Drawn = 0;
Lost = 0;
Points = 0;
}
public String getTeamName(){
return TeamName;
}
public String getShortName(){
return ShortName;
}
public int getPlayed(){
return Played;
}
public void getGoalsFor(int InsertGoalsFor){
GoalsFor = InsertGoalsFor;
}
public void getGoalsAgainst(int InsertGoalsAgainst){
GoalsAgainst = InsertGoalsAgainst;
}
public int getGoalDifference(){
return (GoalsFor - GoalsAgainst);
}
public int getWon(){
return Won;
}
public int getDrawn(){
return Drawn;
}
public int getLost(){
return Lost;
}
public int getPoints(){
return Points;
}
public void play(Match match){
Played++;
int GoalsFor = match.getHomeGoals();
int goalsForThisMatch = match.getHomeGoals();
int goalsAgainstThisMatch = match.getAwayGoals();
String homeTeam = match.getHomeTeamName();
String ShortName = match.getHomeTeamName();
if (ShortName.equals(TeamName)){
ShortName = homeTeam;
} else {
ShortName = match.getAwayTeamName();
}
if (goalsForThisMatch > goalsAgainstThisMatch){
Won++;
}
else if (goalsForThisMatch == goalsAgainstThisMatch){
Drawn++;
}
else {
Lost++;
}
}
}
I believe the problem you're having is that the fields of your Team class are not being updated when you invoke the play method.
The reason you see this behavior is that you're defining local variables inside the play method that hide your class member variables:
public void play(Match match){
...
int GoalsFor = match.getHomeGoals();
int goalsForThisMatch = match.getHomeGoals();
int goalsAgainstThisMatch = match.getAwayGoals();
String homeTeam = match.getHomeTeamName();
String ShortName = match.getHomeTeamName();
...
Your GoalsFor and ShortName local variables defined inside this method are hiding the class member variables you defined at the top of the class:
public class Team
private String TeamName;
private String ShortName;
private int Played;
private int GoalsFor;
...

How to know how many times a method has been called from main class?

My problem is to find out how many times the weight() method is being called from the main class. I should calculate it in the totalWeightsMeasured() method.
The output of the code should be 0,2,6. (EDIT// I had earlier here 0,2,4 but the output should really be 0,2,6)
But I just don't have any idea how can you calculate it and I have tried to google and everything but I just don't know how to do it. (and you are not supposed to add any more instance variables)
CLASS:
public class Reformatory
{
private int weight;
public int weight(Person person)
{
int weight = person.getWeight();
// return the weight of the person
return weight;
}
public void feed(Person person)
{
//that increases the weight of its parameter by one.
person.setWeight(person.getWeight() + 1);
}
public int totalWeightsMeasured()
{
return 0;
}
}
MAIN:
public class Main
{
public static void main(String[] args)
{
Reformatory eastHelsinkiReformatory = new Reformatory();
Person brian = new Person("Brian", 1, 110, 7);
Person pekka = new Person("Pekka", 33, 176, 85);
System.out.println("total weights measured "+eastHelsinkiReformatory.totalWeightsMeasured());
eastHelsinkiReformatory.weight(brian);
eastHelsinkiReformatory.weight(pekka);
System.out.println("total weights measured "+eastHelsinkiReformatory.totalWeightsMeasured());
eastHelsinkiReformatory.weight(brian);
eastHelsinkiReformatory.weight(brian);
eastHelsinkiReformatory.weight(brian);
eastHelsinkiReformatory.weight(brian);
System.out.println("total weights measured "+eastHelsinkiReformatory.totalWeightsMeasured());
}
}
The trick is to use the existing instance variable weight, which is not used yet, as the counter.
public class Reformatory
{
private int weight;
public int weight(Person person)
{
int weight = person.getWeight();
this.weight++;
// return the weight of the person
return weight;
}
public void feed(Person person)
{
//that increases the weight of its parameter by one.
person.setWeight(person.getWeight() + 1);
}
public int totalWeightsMeasured()
{
return weight;
}
}
As pointed out by Satya, introduce a static counter variable as follows:
public class Reformatory {
private static int weightMessurements = 0;
public int weight(Person person) {
// increment counter
weightMessurements++;
// messure weight
return person.getWeight();
}
public void feed(Person person) {
// increase weight
person.setWeight(person.getWeight() + 1);
}
public int totalWeightsMeasured() {
int result = weightMessurements;
// reset counter so that the output matches 0,2,4 instead of 0,2,6
weightMessurements = 0;
return result;
}
}
I think I have the solution which will not require you to add any instance or static variables whatsoever.
Since inside this block of code you already have a local variable named weight.
public int weight(Person person) {
int weight = person.getWeight();
/return the weight of the person
return weight;
}
Therefore, in the scope of that method you have two variables called weight but one is an instance variable and one is a local variable. You can differentiate between the two by writing this.weight for the instance variable, or just weight for the local variable.
All you need to do is to rename the current instance variable weight to weightsMeasured so that it clearer which variable you are referring to.
And then simply add weightsMeasured++ into the weight(Person person) method and return weightsMeasured from the totalWeightsMeasured() method.
So the final code would look like this:
public class Reformatory
{
private int weightsMeasured; //Renamed instance variable
public int weight(Person person) {
weightsMeasured++; //instance variable incremented
int weight = person.getWeight(); //This is the local variable
//return the weight of the person
return weight;
}
public void feed(Person person) {
//that increases the weight of its parameter by one.
person.setWeight(person.getWeight() + 1);
}
public int totalWeightsMeasured() {
//return the number of times the method was called
return weightsMeasured;
}
}
So rather than adding any new variables, we just renamed the existing instance variable that wasn't being used.
A slightly modified and shorter version of the above answers is:
public class Reformatory {
private int weight;
public int weight(Person person) {
this.weight++; //count the number of times when the weight gets measured.
return person.getWeight();
}
public int totalWeightMeasured() {
return weight; //return the number of times when the weight gets measured.
}
}

Conditional static field possible?

I have a class as follows:
public class Level{
public int level;
public int score;
}
Basically, I would want to behave the score as static for a particular value of level. For example,in a competition, a team has multiple competitors, each contributes to the score for a particular level. I wish to add each of their contributions to the score whenever level is equal.
I was wondering if it could be done this way.
EDIT
I feel the problem will be more easy to visualise if I change my Class a bit like this:
public class Participants{
public String name;
public String teamID;
public int[] levelScores; //where the level is denoted
//by the index of this array
}
Now, for all participants with the same teamID, the levelScores must be shared and contribution of any participant object with same teamID must be added to the corresponding levelScore.
That involves changing the code and is unlikely to be worth the extra complexity IMHO. I would just use the code you have (and make the fields final if you can)
abstract Level {
public int getLevel();
public int getScore();
}
class LevelOne extends Level {
public int getLevel() { return 1; }
public int getScore() { return LEVEL_ONE_SCORE; }
}
class LevelTwo extends Level {
private final int score;
public int getLevel() { return 2; }
public int getScore() { return score; }
}
class LevelN extends Level {
private final int level;
private final int score;
public int getLevel() { return level; }
public int getScore() { return score; }
}
Change to using accessor methods (getters/setters) and do this:
class Level {
private static int levelOneScore;
private int level;
private int score;
public int getLevel (
return level;
);
public int getScore() {
return level == 1 ? levelOneScore : score;
}
public void setScore(int score) {
if (level == 1) {
levelOneScore = score;
} else {
this.score = score;
}
}
}
I've omitted the setLevel() method because it feels like level should be final. If level is final, you could (and should) implement this as a separate class that overrides the get/set score methods.
Just had a look at your profile... you're learning by yourself, so I'm assuming that you won't use anything like JNDI, Spring or any other kind of container or framework.
The simplest way of doing this without resorting to a completely static class hierarchy is to use the level as a key to reference the score:
public class Level {
private static Level instance = null;
private static Map<Integer, Integer> scoreMap = new HashMap<Integer, Integer>();
public static Level getInstance() {
if (instance == null) {
instance = new Level();
}
return instance;
}
public static int getScore(int level) {
return scoreMap.get(level);
}
public static void setScore(int level, int score) {
scoreMap.put(level, score);
}
}
Any class that uses Level will do it in this way:
int myLevel = 1; // I assume the class will know its level somehow
Level scoreKeeper = Level.getInstance();
int myScore = scoreKeeper.getScore(myLevel);
This solution uses the horrible Singleton anti-pattern, but it will get you going with what you probably want to achieve.
No, I don't think it is possible. static is only one copy shared across application. You need to think about re-design your code.
STATIC DATA is shared by all the instances of the class. your level 1 instance would share it so does your levelN:).
There is a lot of overhead associated with this answer, but you can create a score class that has one field int score and point all level objects where level = 1 at the score object. That way every time the score is changed, it is changed for all objects that point to it.
It is not possible to do it the way you're thinking.
But it is possible to make a class with a single static method that returns the score to the appropriate input value.
The method:
public static int(int level) {
if(level==1) {
return //what you want.
}
}
I hope I helped.

Categories

Resources