How to increment an instance with setter? - java

I have a little problem in a simple class.
import java.util.Random;
public class fileTest {
private static Random rand = new Random();;
private int randOne = rand.nextInt(10);
private String strOne = String.format("%02d", this.randOne);
public int getRandOne() {
return randOne;
}
public void setRandOne(int randOne) {
this.randOne = randOne +1;
}
public String getStrOne() {
return strOne;
}
}
My "launcher"
public class launch {
public static void main(String[] args) {
fileTest fileA = new fileTest();
System.out.println(fileA.getStrOne());
//FunctionDoMyStuff...
fileA.setRandOne(fileA.getRandOne());
System.out.println(fileA.getRandOne());
//RandOne is increment
System.out.println(fileA.getStrOne());
//StrOne is not
}
}
My idea is to create a random number and transform it into a string.
After finishing my stuff, I need to increment my string.
But the result after the setter is the same as in the beginning. I think I don't understand everything about a getter/setter.
Can anyone help me to understand my mistake?

This happens once at the time that your instance is created:
private String strOne = String.format("%02d", this.randOne);
It isn't automatically run again after you change randOne. The solution is to remove the strOne field altogether and construct the String inside the getter:
public String getStrOne() {
return String.format("%02d", this.randOne);
}
You don't need to store a dynamically derived value.
The behaviour of your method setRandOne doesn't match what people might reasonably expect a set method to do. A method that does what yours does could be described as setRandOneToOneHigherThan(int value). Or you could call it incrementRandOne() but then the body needs to do this.randOne = this.randOne + 1; (or this.randOne++;). Or you could make it a normal setter and do the incrementing while you call the method: fileA.setRandOne(fileA.getRandOne() + 1);.

Related

Method and Variable Scope Issue in Java

I need help I cannot figure out how to fix the scope of my variables. I want this to be an example for my notes but have been on it for almost 2 hours.
public class methodPractice{
String streetName;
int streetNum;
public static void streetName()
{
String streetName = "Pope Ave.";
}
public static void streetNum()
{
int streetNum = 11825;
}
public static void main(String[] args)
{
streetName();
streetNum();
System.out.println("This is your home adress: " + streetNum +
streetName);
}
}
Thank you for your help.
You are shadowing the fields. Use this to make sure you get the fields, or a compile error.
public static void streetName()
{
this.streetName = "Pope Ave.";
}
public static void streetNum()
{
this.streetNum = 11825;
}
Here is your main method, with line numbers added:
1. public static void main(String[] args) {
2. streetName();
3. streetNum();
4. System.out.println("This is your home adress: " + streetNum + streetName);
5. }
A few points...
When line 2 runs, "streetName()" calls the static method below. The static keyword says you are free to call the method by itself – that is, you don't need an object; you don't need to call new methodPractice() first.
public static void streetName() {
String streetName = "Pope Ave.";
}
When line 3 runs, it's the same thing: "streetNum()" calls a different static method – again, totally fine to call this by itself.
public static void streetNum() {
int streetNum = 11825;
}
Line 4 is different, there are a few things going on. Your expectation is that "streetNum" finds the int that you declared on the class, but it doesn't work. Why? Because you defined that member with "int streetNum" – without "static". So what? Without being declared static, it means "streetNum" belongs to an object instance. What does that look like? Here's an example showing object creation, followed by setting the object member "streetNum" to 1.
methodPractice object = new methodPractice();
object.streetNum = 1;
You could work around this by declaring both of the non-static members to be static (static String streetName, and static int streetNum). Or you could leave them as is, and interact with them through an object instance (after doing new ..).

Getting Variables From Java constructor

I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.

Java - changing a variable through pass-by-value

So I've read about the pass-by-value nature of Java and I've tried to change my variable after passing it to a function by having the function return the variable again. I didn't succeed in that.
My code
public class Logic {
private int position;
public class Logic(){
position = 1;
}
public void appendPosition(){
position = calculatePosition(position);
}
}
This is the barebones code. I call this method from an instance of Logic which is instantiated in another class:
public class MainLogic {
ILogic L;
public MainLogic(ILogic L){
this.L = L;
}
public void start(){
L.appendPosition();
}
}
Through repeated debugging I find to my dismay that the position variable does not change at all. The position variable passed to calculatePosition changes fine, as expected. What am I missing? I've tried making the variable public and static.
calculatePosition
private int calculatePosition(int position){
position += 6;
if(snakeLocations[position]>0) {
position -= 6;
}
else if(ladderLocations[position]>0) {
position += 6;
}
return position;
}
private final int[] snakeLocations = new int[] {0,0,0,0,0,0,0,0,0,9,0,0,0,13,0,0,0,0,0,19,0,0,0,0,0};
private final int[] ladderLocations = new int[] {0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,15,0,0,0,0,20,0,0,0,0};
public class Logic {
private int position;
public Logic(){
position = 1;
}
//to get position.....................
public int getPosition(){
return this.position;
}
public void appendPosition(){
position = calculatePosition(position);
}
private int calculatePosition(int position){
position += 6;
if(snakeLocations[position]>0) {
position -= 6;
}
else if(ladderLocations[position]>0) {
position += 6;
}
return position;
}
private final int[] snakeLocations =
new int[] {0,0,0,0,0,0,0,0,0,9,0,0,0,13,0,0,0,0,0,19,0,0,0,0,0};
private final int[] ladderLocations =
new int[] {0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,15,0,0,0,0,20,0,0,0,0};
}
//next class
public class MainLogic {
Logic L;
public MainLogic(Logic L){
this.L = L;
}
public void start(){
L.appendPosition();
}
public static void main(String[] args) {
Logic L = new Logic();
MainLogic ml = new MainLogic(L);
System.out.println(ml.L.getPosition());
ml.start();
System.out.println(ml.L.getPosition());
}
}
Let's read your code.
// There is a logic class.
public class Logic {
// So Logic has a position. it starts with zero.
private int position;
// Logic also has an inner class, also called Logic.
public class Logic(){
position = 1;
// When a new Logic().Logic() is created, the instance
// variable of the parent instance gets set to one. WHAT?!?
}
// ... lots of code
}
So, It's a bit like that Yo Dawg! meme - I heard you like Logic, so we've put A logic instance into your Logic instance so you can Logic while your Logic.
You probably want a constructor.
// So this is Logic.
public class Logic {
private int position;
// When an Logic instance is created, position starts with 1.
public Logic(){
this.position = 1;
}
Ok. So we're not talking about Yo Dawg Memes.
So Let's talk pass by value.
Pass-by-value means classes are like very egotistic children: You can't play with their toys, unless they tell you so.
This is a good thing® since this means only the owning instance is allowed to change their private state. Trust me, it prevents quite a bit of havoc.
One way to allow the outside world to actually change the state is by using query and mutator methods. Back in the day, we used to call them getter and setter, but that sounds too simple, so software architects will usually use the fancier term.
But... all of this doesn't really apply since calculatePosition() is defined at Logic. Oops.
Let's try this:
Renaming some instance variables
Be a bit verbose to help the debugger. baby steps.
(Also, dropping a few jokes to fish for upvotes).
public class Logic {
private int position = 1;
public void appendPosition(){
// When debugging strange stuff,
// keep each step simple.
// Is calculatePosition working as it should?
int newPosition = calculatePosition(this.position);
this.position = newPosition;
}
// Always use parameters as final. It's good karma.
// You don't NEED to declare them as final,
// but let's try to be EXTRA clear.
private int calculatePosition(final int targetPosition){
// Yes, make as much as you can immutable
// You'll save a ton of mental bandwidth.
final int localCopy = targetPosition +6;
if(snakeLocations[localCopy]>0) {
return (localCopy -6);
// Don't force the maintenance programmer to
// read all your stuff. Return often, return early.
// This isn't Cc++, where you need to
// actually free your reference/pointers,
// so there's no point enforcing a single return.
}
if(ladderLocations[localCopy]>0) {
return (localCopy+6);
}
return localCopy;
}
}
So... Did this worked as it should?
I found the answer. This is often my mistake in posting here. I try to strip down my code as much as possible to ease the work for you guys, but sometimes the problem lies outside of the scope of what I provide due to a lack of understanding, or oversight, on my part.
I was actually calling MainLogic from two levels above:
public mainFrame() {
initComponents();
logic = Factory.getMainLogic();
}
where
public static class Factory {
public MainLogic getMainLogic(){
PlayerLogic pL = new PlayerLogic();
ImageLogic iL = new ImageLogic();
DieLogic dL = new DieLogic();
MainLogic mainLogic = new MainLogic(pL,iL,dL);
return mainLogic;
}
}
I forgot I had accidentally put Factory as static. My sincerest apologies for wasting your time.

how to stop getting the same number when generating 2 numbers from a different class

When I run this code i get 2 numbers (which is good) but the numbers generated are the same (which is bad) and I dont want the numbers to be the same. I've done this as an experiment for a rpg I was going to make so I thought it would be beter if each weapon had a different class.
The main class:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str);
System.out.print(BasicAxe.Str);
}
}
The basic axe class:
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str = rnd.nextInt(4)+5;
}
This line:
static int Str = rnd.nextInt(4)+5;
declares a static variable and initializes it once. If you want the code to run each to you access Str, you should make it a method:
public static int getStrength() {
return rnd.nextInt(4)+5;
}
Then call it with this code in Main.main:
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
An alternative which would probably be more object-oriented would be to make the strength an instance field, so that each axe created had a possibly-different (but persistent) strength:
public class BasicAxe {
private static final Random rnd = new Random();
private final int strength;
public BasicAxe() {
strength = rnd.nextInt(4)+5;
}
public int getStrength() {
return strength;
}
}
Then in Main.main:
BasicAxe axe1 = new BasicAxe();
BasicAxe axe2 = new BasicAxe();
System.out.println(axe1.getStrength());
System.out.println(axe2.getStrength());
System.out.println(axe1.getStrength());
Here, the first and third lines of output will be the same - but the second will (probably) be different.
You're generating a single random number and printing it twice. Try something like this instead:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str());
System.out.print(BasicAxe.Str());
}
}
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str() { return rnd.nextInt(4)+5; }
}
This because this line
static int Str = rnd.nextInt(4)+5;
runs just one time in whole the lifecycle of your application. It's static value, you should use static method instead.
Because you define the Str variable as static, only a single copy of that variable is shared between all your BasicAxe classes.
The way to get a different answer each time you ask for the int value is, to use the example posted by the previous poster,
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
But, if you want to create an actual instance of the class BasicAxe, which keeps it's value so that each time you ask for the strength you get the same value, you'll need something different.

How to test an int has been incremented using Junit?

I have the following method that I would like to test, it simply increments an int if a Boolean condition is true:
public void incrementIfConditionMet(Boolean personCheckedIn) {
int peopleInHotel=0;
if (personCheckedIn==true){
peopleInHotel++
}
}
I am very new to unit testing in Java. How can I unit test this to check if the int has been incremented or not?
Currently your value of peopleInHotel cannot be accessed outside the method, as it was created internally. If you want to access it, you should do the following:
private int peopleInHotel=0;
public int getPeopleInHotel() {
return peopleInHotel;
}
public void incrementIfConditionMet(Boolean personCheckedIn) {
if (personCheckedIn){
peopleInHotel++
}
}
Now in your test class, you can check by calling getPeopleInHotel();
So the test case would be:
int initalValue = classInstance.getPeopleInHotel();
classInstance.incrementIfConditionMet(true);
assertEquals(classInstance.getPeopleInHotel(), initalValue +1);
This would also fix your issue where you don't keep the value once the method has been ran. At the moment, in your current code setup, your variable of peopleInHotel is discarded after you've finished with the method.
int peopleInHotel=0;
public void incrementIfConditionMet(Boolean personCheckedIn) {
if (personCheckedIn==true){
peopleInHotel++
}
}
public int getPeopleInHotel() { //test the returned value after you've incremented
return peopleInHotel;
}
Try like this:
public class Hotel {
private int peopleInHotel = 0;
//a constructor...
public int getPeopleInHotel() {
return this.peopleInHotel;
}
public void incrementIfConditionMet(Boolean personCheckedIn) {
if (personCheckedIn==true){
peopleInHotel++
}
}
}
In your Unit-Test, you now can do something like that:
//defining your TestCase
Hotel hotel = new Hotel();
int initValue = hotel.getPepleInHotel();
hotel.incrementIfconditionmet(true);
assertEquals(hotel.getPeopleInHotel(),initValue+1);

Categories