how to write accessor and mutator? - java

calculate the amount of gas lost and set the car's current gas capacity to the new value. I forgot to add this part to the question. the amount of gas does not exceed the top gas capacity. I would like to know is this right?
private final int GAS_CAP = 30
public int getGasCapacity(int gasCapacity)
{
if(currentGas <= GAS_CAP)
{
gasCapacity = GAS_CAP - currentGas;
}
else gasCapacity = currentGas;
return gasCapacity;
}

Your method doesn't mutate the state of the object, it just returns a value. You only assign a value to the gasCapacity parameter of the method, which is local to the method.
If it's supposed to mutate something, then you got this wrong.
In addition, you are not doing anything with the value passed to your method in the gasCapacity variable, so your logic seems incorrect.

You will probably need two methods for this, one to get the current gas (accessor) and one to set it (mutator).
public int getGasLost(){
return GAS_CAP - currentGas;
}
public void setGasCapacity(int gasCapacity){
GAS_CAP = gasCapacity;
}
However, since GAS_CAP seems to be a final value, you won't be able to change it, can you confirm this?

Related

Setting the value of a variable from another class in Java

I was wondering if it is possible to reset the value of a variable from another class. For example I have this variable in a HillClimber (hc) class:
public int ballWeight = 200;
What I want to do is run a simulation of a game with the ball weighting at this value. When it is finished I want to set the value to 201 from another class and begin the simulation again, and after that increase to 202 and start another and so on. My problem is that every time I restart the simulation the ballWeight variable is reset to 200. I have tried using a setter method in the HillClimber class:
public int setBallWeight(int ballWeight) {
return this.ballWeight = ballWeight;
}
and called it from another class at the end of a simulation:
hc.setBallWeight(hc.ballWeight+1);
but this does not seem to work as the variables stored value is not changed. Does anyone know how I can do this so the stored value of ballWeight will be increased by 1 each time a simulation ends? Or is this even possible? Thanks.
Usually in a POJO you have what are called a getter and a setter method for every variable of the object. In your case:
public class HillClimber{
private int ballWeight;
public HillClimber(){
this.ballWeight = 200;
}
public void setBallWeight(int ballWeight){
this.ballWeight = ballWeight;
}
public int getBallWeight(){
return this.ballWeight;
}
}
In this way you can access the variable ballWeight via get and set method. You don't access it directly like in hc.ballWeight, which is possible but is a bad practice, and prevent this access type declaring your variable as private (meaning that only the class in which it is declared can directly access it).
To fullfill your request of adding one at every run of the game you can therefore call
hc.setBallWeight(++hc.getBallWeight()); //Equivalent to hc.setBallWeight(hc.getBallWeight() + 1);
I usually don't use this approach if the class isn't automatically generated (as in an Hibernate context), but instead declare another method in the HillClimber class
public void incrementBallWeight(int ballWeightToAdd){
this.ballWeight += ballweiGhtToAdd; //Equivalent to this.ballWeight = this.ballWeight + ballweiGhtToAdd;
}
or if I always need to add only one to my variable
public void incrementBallWeight(){
this.ballWeight++;
}
and then simply call incrementBallWeight after every game run.
NB: to have this working you will have to use always the same instance of HillClimber. In your main
public class Game{
private HillClimber hc = new HillClimber(); //Create the instance and sets ballWeight to 200
public static void main(String[] args){
playGame();
hc.incrementBallWeight(); //ballWeight == 201
playAnotherGame()
hc.incrementBallWeight(); //ballWeight == 202 -> Always the same instance of HillClimber (hc)
.
.
.
}
}
EDIT
I think your problem is greater than that. You are asking to save the state of a variable ( meaning that this value should be available also if you turn off and on your pc) without using a permanent storage. This is simply unachievable.
You should rethink your program (and I mean java program, not a "game run") to not stop after every game run. You can do this in different ways: via Swing GUI, via user input from stdin and so on. If you want some help on this topic, we need to know more of your code (maybe putting the whole of it is best).
OR you can use a file to store your value, which is not as difficult as you think. (Also).

Avoid reassigning parameters

I’m getting PMD red colored violation
Avoid reassigning parameters such as 'bankRequest'
This is my method
#Override
public BankDTO loadTariff(BankDTO bankRequest, int[] executionLevels) {
double[] fee = null;
for (int level : executionLevels) {
// Check the tariff availability from execution level one to .....
fee = loadCokaAndBankFee(bankRequest,level);
if (fee != null) { // if fee found reload the bank request with new
// amount
bankRequest = reloadBankRequest(bankRequest, fee);
break; // no need to go for any other level deep level cover //
// here.
} // if tariff not found use the esb provided amounts
}
return bankRequest;
}
Could someone explain what wrong with this code. If I ignore it what is the impact.
In your case, there's a parameter named bankRequest. Inside the method, you are assigning bankRequest a value.
By some, it is considered an ill approach to assign values to parameters within a method's body, as it is, at times, confusing. Some developers prefer always assuming that a parameter is never assigned any value during a method's run.
To avoid that, you can declare an alternative variable of type BankDTO:
BankDTO updatedRequest = bankRequest;
...
...
updatedRequest = reloadBankRequest(bankRequest, fee);
...
...
return updatedRequest;
You should avoid re assigning variables for the reasons already given. Anyway,instead of assigning a new variable consider just returning from the loop when finding the correct value. Thiswould also make "break" redundant.
In java parameters are called by reference. In your case this means, if you change the object bankRequest it is not visible outside of the method loadTariff.
After the line bankRequest = reloadBankRequest(bankRequest, fee); the variable bankRequest points to a different object of BankDTO.
If you want to change internal values of bankRequest and use it after calling loadTariff you should do something like bankRequest.loadRokaAndBankFee(fee).
Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.
Example(s):
public class Foo {
private void foo(String bar) {
bar = "something else";
}
}
reference: http://pmd.sourceforge.net/pmd-5.0.1/rules/java/design.html
Reassigning values to the incoming parameters is not recommended. Use temporary local variable.
public BankDTO loadTariff(BankDTO bankRequest, int[] executionLevels) {
double[] fee = null;
BankDTO updatedBankRequest = bankRequest;
for (int level : executionLevels) {
fee = loadCokaAndBankFee(bankRequest,level);
if (fee != null) {
updatedBankRequest = reloadBankRequest(bankRequest, fee);
break;
} }
return updatedBankRequest;
}

Java - Error in eclipse: the left hand side of an assignment must be a variable

This is a small part of my code. My project is to simulate a whole school system. To add teachers, courses etc. All of my class members are private, so i created setters and getters methods. I try to give to 'teachersNum' a value and this must be automatic(not from keyboard). So i want to give it value 1 if its the first teacher etc. I hope you can understand. Sorry for my English.
public void addTeachersList(Teachers teachers) {
if(this.teachersSize<100){
this.teachersList[this.teachersSize] = teachers;
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
this.teachersSize++;
}
}
You'll have to call a setter:
this.teachersList[this.teachersSize].setTeacherNum(this.teachersSize-1);
Calling the getter getTeacherNum just gives you the number, it isn't a reference to that property.
Although I must say, you'd really do yourself a favor by using a List implementation instead of arrays.
In this line
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
getTeacherNum() returns a value. You can't assign to it.
You have the problem here
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
.getTeacherNum() will return a value which must be stored in a variable on left side.
eg:
temp = .getTeacherNum();
And its better to use a static variable to keep the count of teachers, so every time a teacher is created he/she gets a nos which is different from the previous one
eg:
xxxx001
xxxx002
xxxx003
You have the problem here
this.teachersList[this.teachersSize].getTeacherNum() = this.teachersSize -1;
.getTeacherNum() will return a value which must be stored in a variable on left side.
eg: temp = .getTeacherNum();
And its better to use a static variable to keep the count of teachers, so every time a teacher is created he/she gets a nos which is different from the previous one
eg:
xxxx001
xxxx002
xxxx003

How to write a recursive function using static variables

I am trying to write a code to get the set of points (x,y) that are accessible to a monkey starting from (0,0) such that each point satisfies |x| + |y| < _limitSum. I have written the below code and have used static HashSet of members of Coordinate type (not shown here) and have written a recursive method AccessPositiveQuadrantCoordinates. But the problem is the members of the HashSet passed across the recursive calls is not reflecting the Coordinate members added in previous calls. Can anybody help me on how to pass Object references to make this possible? Is there some other way that this problem can be solved?
public class MonkeyCoordinates {
public static HashSet<Coordinate> _accessibleCoordinates = null;
private int _limitSum;
public MonkeyCoordinates(int limitSum) {
_limitSum = limitSum;
if (_accessibleCoordinates == null)
_accessibleCoordinates = new HashSet<Coordinate>();
}
public int GetAccessibleCoordinateCount() {
_accessibleCoordinates.clear();
Coordinate start = new Coordinate(0,0);
AccessPositiveQuadrantCoordinates(start);
return (_accessibleCoordinates.size() * 4);
}
private void AccessPositiveQuadrantCoordinates(Coordinate current) {
if (current.getCoordinateSum() > _limitSum) { return; }
System.out.println("debug: The set _accessibleCoordinates is ");
for (Coordinate c : _accessibleCoordinates) {
System.out.println("debug:" + c.getXValue() + " " + c.getYValue());
}
if (!_accessibleCoordinates.contains(current)) { _accessibleCoordinates.add(current); }
AccessPositiveQuadrantCoordinates(current.Move(Coordinate.Direction.East));
AccessPositiveQuadrantCoordinates(current.Move(Coordinate.Direction.North));
}
I will give points to all acceptable answers.
Thanks ahead,
Somnath
But the problem is the members of the HashSet passed across the recursive calls is not reflecting the Coordinate members added in previous calls.
I think that's very unlikely. I think it's more likely that your Coordinate class doesn't override equals and hashCode appropriately, which is why the set can't "find" the values.
As an aside, using static variables like this seems like a very bad idea to me - why don't you create the set in GetAccessibleCoordinateCount() and pass the reference to AccessPositiveQuadrantCoordinates, which can in turn keep passing it down in the recursive calls?
(As another aside, I would strongly suggest that you start following Java naming conventions...)
i don't see any problem with making the field _accessibleCoordinates non-static
and you should know that HashSet does not guarantee the same iteration order everytime, you could better use a LinkedList for that purpose...
and about pass by reference, i found this post very useful
java - pass by value - SO link
From what you are doing you would be updating _accessibleCoordinates in every recursive call correctly.

Array parameter passing

I'm in a beginner's java class. This Lab is for me to make a class "Wallet" that manipulates an array that represents a Wallet. Wallet contains the "contents[]" array to store integers represing paper currency. The variable "count" holds the number of banknotes in a wallet. After writing methods (that match provided method calls in a serpate Driver class) to initialize the Wallet and add currency/update "count", I need to transfer the array of one instantiated Wallet to another. I don't know how that would work because the one Wallet class has only been messing with a wallet called "myWallet" and now I need to take a new Wallet called "yourWallet" and fill it with "myWallet"'s array values.
//I should note that using the Java API library is not allowed in for this course
My Wallet class looks like this so far:
public class Wallet
{
// max possible # of banknotes in a wallet
private static final int MAX = 10;
private int contents[];
private int count; // count # of banknotes stored in contents[]
public Wallet()
{
contents = new int[MAX];
count = 0;
}
/** Adds a banknote to the end of a wallet. */
public void addBanknote(int banknoteType)
{
contents[count] = banknoteType;
count = count + 1;
}
/**
* Transfers the contents of one wallet to the end of another. Empties the donor wallet.
*/
public void transfer(Wallet donor)
{
//my code belongs here
}
...
The Driver code looks like this:
public class Driver
{
public static void main(String args[])
{
Wallet myWallet = new Wallet();
myWallet.addBanknote(5);
myWallet.addBanknote(50);
myWallet.addBanknote(10);
myWallet.addBanknote(5);
System.out.println("myWallet contains: " + myWallet.toString());
// transfer all the banknotes from myWallet to yourWallet
Wallet yourWallet = new Wallet();
yourWallet.addBanknote(1);
yourWallet.transfer(myWallet);
System.out.println("\nnow myWallet contains: "
+ myWallet.toString());
System.out.println("yourWallet contains: "
+ yourWallet.toString());
I want to use addBanknote() to help with this, but I don't know how to tell the transfer() method to transfer all of myWallet into yourWallet.
I had the idea to do somethign like this in transfer():
yourWallet.addBanknote(myWallet.contents[i]);
with a traversal to increase i for myWallet contents. It seems horribly wrong, but I'm at a complete loss as to write this method.
If my problem is so unclear that nobody can help, I would be more than happy to receive advice on how to ask a better question or on how to search with correct terms.
Thanks for any help you can provide.
I don't want to spoil your homework as you seem to be going the right way, but I do have some comments which you may either take or not :)
First, I would probably put the bank note types in some enumeration. But as that sounds a bit to advanced, consider
public class Wallet {
public static final int ONE_DOLLAR_BILL = 1;
public static final int FIVE_DOLLAR_BILL = 5;
...
// looks a bit more readable to me
myWallet.addBanknote(ONE_DOLLAR_BILL);
Transferring all the banknotes from the donor to yourself should not be so much of a problem
(a for loop would do) but I think you're in a world of hurt if you are trying to implement a
removeBanknote(int banknoteType);
as you are using count not only as a length but also as an index variable. By this I mean that you assume contents[0] ... contents[count-1] hold valid banknotes. And how do you remove one without too much work?
Warning: a bit more advanced
In your case I would probably opt to have a banknoteType of 0 indicating an empty banknote slot in your wallet, and implement _addBanknote(int banknoteType) as:
public void addBanknote(int banknoteType) {
for (int i=0; i < contents.length; i++) {
if (contents[i] == 0) {
contents[i] = banknoteType;
count++;
return; // OK inserted banknote at the first empty slot
}
}
throw new RuntimeException("Wallet is full");
}
This may be a bit overwhelming at this point. But it would allow you to implement:
public void removeBanknote(int banknoteType) {
for (int i=0; i < contents.length; i++) {
if (contents[i] == banknoteType) {
contents[i] = 0; // better: NO_BANKNOTE = 0
count--;
return;
}
}
throw new RuntimeException("This wallet does not contain a banknote of type " + banknoteType);
}
Please note that in both methods I return when I successfully removed or added the banknote. Only when I could not find a free slot, or the requested banknote, I finish the for loop and end up throwing an exception and thereby stopping the program.
I think the question is fine and I think you're on the right path. The way you're calling Wallet#addBanknote(int) is correct. What you have said is the right thing:
public void transfer(Wallet donor)
{
// Traverse the donor's wallet
// Add the bank note from the donor to this wallet
// What do you think also needs to happen to make sure
// the donor is actually giving their bank note?
}
Just another thing, what would happen in your Wallet#addBanknote(int) method if you have more contents than the MAX?
You can create either a constructor that takes another wallet, or a function (as already mentioned) and use System.arraycopy to copy the array in one fell swoop. System.arraycopy is fast, and its definitely overkill for something small like this, but its good tool to have in your toolkit.
The other alternative mentioned, copy the elements from one array to the other element by element in a loop will work fine too.
The myWallet inside the transfer method is named 'donor', and with that, it doesn't look horribly wrong:
addBanknote (donor.contents [i]);
You just need a loop around it, and to remove the yourWallet. which is the name of an instance of that class. That instance is inside the Class/method this, but needn't be specified, because there is no other addBanknote-Method in scope, which could be meant. (Thanks to mangoDrunk).

Categories