When creating new objects, my counter stays the same number - java

I working on a program where I need to count the how many objects are created by a certain class (and all its sub-classes). I made a quick test program that replicated my problem:
public class Test {
private int number = 0;
public Test(){
number++;
}
public int returnNumber(){
return number;
}
}
How do I make the variable 'number' save its value, instead of initializing every time I create a new object?

Make number static in order for it to have the same value for all instances of your class.
private static int number = 0
You might want to change your returnNumber to be static too.
If you want each instance of your class to have a unique number, you should keep that number in a separate member :
public class Test {
private int number = 0;
private static int counter = 0;
public Test(){
number = counter++;
}
public int getNumber() {
return number; // each instance will have a unique value
}
public static int getCounter () {
return counter; // this will return the current value of the counter
}
}

number needs to be a static type so its shared across all instances of your class.
Consider private static int number = 0 instead.
Better still, you ought to make number an atomic type, so multiple constructors can be called on several threads. (Otherwise you could end up underestimating number.)
Consider using AtomicInteger as the type; still static of course.

create variable as static
private static int number = 0;

Make it
private static int number = 0;

public class Test {
private static int number = 0;
public Test(){
number++;
}
public int returnNumber(){
return number;
}
}

Related

Increasing an objects instance variable by one with each new object created in Java

I am working on a problem. I had to create a Boat class and that boat has-a serial number that increases by 1 each time a new object is made. My tests passed for the createNewSerialNumber() method but when I test it on the Boat object, I keep getting the error that the AssertionFailed, expecting <2> but was <1> or <7> but was <6> meaning that the object's serial number is not incrementing by one like it should.
I have gone over static vs not static and thought I was doing it correctly. I even checked it against other similar problems and still the same.
Anyone out there with any guidance?
private int counter =0;
private static int serialNumber = 0;
public static int createNewSerialNumber()
{
serialNumber++;
return serialNumber;
}
public static int getSerialNumber()
{
return serialNumber;
}
public Boat(String newMake, Color newColor)
{
make = newMake;
color = newColor;
speed = 0;
counter++;
serialNumber = counter;
}
Only the static variable should be incremented. The counter instance variable should be assigned the incremented value.
public Boat(String newMake, Color newColor)
{
make = newMake;
color = newColor;
speed = 0;
counter = createNewSerialNumber();
}
This way, the first Boat instance will have counter == 1, the second will have counter == 2, and so on.
You should also make the createNewSerialNumber method private, since serialNumber shouldn't be incremented from outside this class. Only the Boat constructor should increment it.

Can you reset a static variable?

I have been trying to reset a static variable that will keep count when certain methods are run. I want to be able to reset the counter after I return the output of one of the methods. The getEfficency will pull the value just fine, but after I run the getEfficency I would like for the static variable to be reset to 0, so that my program can run the other compute method.
public class Sequence {
private static int efficencyCount;
public static int computeIterative(int n) {
efficencyCount++;
}
public static int computeRecursive() {
efficencyCount++;
}
public static int getEfficiency() {
return efficencyCount;
}
}
Just use a temp variable and set hour static to 0.
Also you should keep protected your static variables to avoid misuse of your variables lutside of your class.
public static int getEfficiency (){
int temp=efficiencyCount;
efficiencyCount=0;
return temp;
}
You can create a local variable and store the value of count temporarily. Reset the value of efficencyCount and return the value of local temporary count variable.
public static int getEfficiency() {
int count = efficencyCount;
efficencyCount = 0;
return count;
}
You could do it as below:
Create a method, and reset the efficencyCount variable inside this method
public static void resetCounter() {
efficencyCount = 0;
}
Create a temporary variable that holds the efficencyCount, then reset efficencyCount to zero.
public static int getEfficiency(){
int temp = efficencyCount;
efficencyCount = 0;
return temp;
}

Prime static array for a number class

I would like to make a Number class that has a static set of prime numbers.
I want the numbers to be stored in a static set for the class but I want to add the numbers to the set as the class is asked to find prime numbers. As in I only want to add numbers to this set when a separate method for testing a prime number is called and a prime number is found.
For some reason the static final set erases itself when another class uses this class (Number).
Here is some of my code for the Number class.
public class Number {
private int number;
static final HashSet<Integer> pSet = new HashSet<>();
static {
pSet.add(2);
}
public Number(int n) {
number = n;
}
public boolean isPrime() {
boolean out = true;
if (number == 1) { return true; }
if (pSet.contains(number)) { return true; }
for (int i : pSet) {
if (number%i == 0) {
out = false;
break;
}
}
if (out) { pSet.add(number); }
return out;
}
}
How can I make this set not override itself but not be statically defined?
I'm a bit confused. In the code that you have posted up, the Set should not be erased, because you have defined it as static. Are you saying that when you make it not static, then it gets erased when you call the class?
I'm assuming that the class works as you have posted it, but you want to make the Set non-static, but that when you do that, it gets erased.
So the first thing to do is:
private final HashSet<Integer> pSet = new HashSet<>(); // Changed to private
The problem, then, is that your calling code has to say
Number n = new Number(15); // Or whatever number you're calling it with
so every time you call it, it gets a fresh copy of Number and your Set is gone.
So instead, make your calling code only create one Number(), but have a new method in Number that looks like:
public void setNumber(int n){
number = n;
}
Then every time you want to call number, you can call
number.setNumber(5);
number.isBoolean();
the original post, contained some misunderstandings.. here is a suggested fix:
public class Number
{
public static HashSet<Integer> pSet;
static
{
pSet = new HashSet<>();
pSet.add(2);
}
public static boolean isPrime(int n)
{
boolean out = true;
if (n == 1) { return true; }
if (pSet.contains(n)) { return true; }
for (int i = 2; i < n; i++)
{
if (n % i == 0) {
out = false;
break;
}
}
if (out) { pSet.add(n); }
return out;
}
}
in my opinion 'isPrime' method should be static.. there is no point to create an instance of a class just to run a test over a number
the role of pSet (as declared by the submitter) is to hold a cache of previously tested prime numbers (so every number tested once)

Incrementing a number and then setting back after fixed records arre entered?

Actuallt I want to set a varaiable as 6 digit number, incrementing it and resetting it back whent the record reaches 999999. I want to increment the value only when I perform a certain call to the web service through my client that is written in Java. Can you please suggest any method for doing? Any other way then creating a database and entering the value in that and then flushing the values when the count reaches 999999.
Thanks
I'll write an example in a singleton but I recommend using spring or container equivalent to use 1 single bean to do this.
public class Counter {
private static Counter instance;
private static int COUNT_MAX_VALUE = 1000000;
public static synchronized Counter getInstance() {
if (instance == null) {
instance = new Counter();
}
return instance;
}
// -- end of static features --
private int counter;
public Counter() {
this.counter = 0;
}
// return result
public synchronized int getCount() {
return counter;
}
// increment by 1, then return result
public synchronized int addAndGetCount() {
addCount();
return getCount();
}
// increment by 1
public synchronized int addCount() {
if (++counter >= COUNT_MAX_VALUE) {
counter = 0;
}
}
}

Method cannot modify input int parameter

Not to sure why the integers lowRange and highRange are not going between these classes.
package guessnumber;
public class GuessNumber
{
static public int computerGenedNumber;
static public int lowRange;
static public int highRange;
static public int playerGuess;
public static void main(String[] args)
{
Input.range(lowRange, highRange);
Rand.number(lowRange, highRange, computerGenedNumber);
Input.guess();
Give.result();
}
}
Next Class:
package guessnumber;
import javax.swing.JOptionPane;
class Input
{
public static void range(int lowRange, int highRange)
{
String rawUserInput;
rawUserInput = JOptionPane.showInputDialog("Please enter the range you wish to guess. (EX: 1-10)", "1-10");
for(int i = 0; i < rawUserInput.length(); i++)
{
if(rawUserInput.charAt(i) == '-')
{
lowRange = Integer.parseInt(rawUserInput.substring(0, i));
highRange = Integer.parseInt(rawUserInput.substring(i + 1, rawUserInput.length()));
}
}
}
static void guess()
{
}
}
And the last relevant one:
package guessnumber;
class Rand
{
static public void number(int lowRange, int highRange, int computerGenedNumber)
{
computerGenedNumber = (int)(Math.random() * (highRange - lowRange) + lowRange);
}
}
The rest of the classes are currently blank so I don't think I need to put them here too.
Here is a simplified piece of code which reproduce your problem, and make sure you understand why it is causing problem and the solution:
class Foo {
public static void square(int a, int result) {
result = a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
Foo.square(a, result);
System.out.println("result " + result);
}
}
This should be fundamental understanding of Java. Checkout what is the meaning of "pass-by-value"
In brief, the parameter passed in the method is a copy of the argument. Therefore when you are changing the parameter in your method, you are just changing another piece of data, and your change is not reflected to caller.
One way to fix is to change the method and return your result, which looks like:
class Foo {
public static int square(int a) {
return a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
result = Foo.square(a);
System.out.println("result " + result);
}
}
Another common solution is to pass in a "holder object" as the result. Although the object reference is passed by value, that copy of object reference is still pointing to the same object as caller. I won't go too deep into this as it is less common and you should be able to get the proper way doing so once you have better understanding on how value (including object reference) is passed around.
Parameters are passed "by value" in Java. What that means is that when you call
input.range(lowRange, highRange);
it gives the current values of those variables to input.range, but it doesn't give input.range a way to modify them. In the range method:
public static void range(int lowRange, int highRange)
the parameters lowRange and highRange (which have no connection with the variables in GuessNumber, even though the names are the same) are copies of what you pass in. When you assign lowRange = ... in the method, it changes the copy but has no effect at all on the lowRange and highRange in GuessNumber.
You need to write a range method that returns two values. This needs a little bit of work, but I'd write a Range class that has low and high members, and then change your method to
public static Range range()
That method would have to create a new Range object. I think it's OK for low and high to be public members of Range:
class Range {
public int low;
public int high;
public Range(int low, int high) {
this.low = low;
this.high = high;
}
}
Normally, public data in a class is a bad thing, but for a class whose only purpose is to let a method return multiple values, it's OK in my opinion.

Categories

Resources