Auto-Increment id in java - java

Team one and Team two have both id 0? What am I doing wrong? I'm just trying to auto increment the id every time a new object is made.
This is code from Team.java
public class Team{
private int teamId;
public Team(){
this.teamId= teamId++;
}
public void printTeamId(){
System.out.println(this.teamId);
}
}
This is code from Main.java
public class Main {
public static void main(String[] args) {
Team one= new Team();
Team two= new Team();
one.printTeamId();
two.printTeamId();
}
}

You need an extra static variable to store the amount of teams. static means that all the objects share this variable. Every team has it's own variable teamId, but share the variable teamIdCounter
public class Team{
private int teamId;
private static int teamIdCounter = 0;
public Team(){
this.teamId= teamIdCounter++;
}
public void printTeamId(){
System.out.println(this.teamId);
}
}
If you are using multiple threads, check the other answers on how to use AtomicInteger to count your objects threads-safe.

About the static variable is ok but if you want to be thread safe use Atomic Integer.
public class Team{
private int teamId;
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public Team(){
this.teamId= atomicInteger.incrementAndGet();
}
public void printTeamId(){
System.out.println(this.teamId);
}
}
This will make a thread safe counter instead a static counter that will not be thread safe.

Make your teamId variable static & initialize it with some integer value (recommended is -1).
Using initial value -1 cause first teamId = 0.

Related

Understanding reflection's strange behavior

I was writing this piece of code to understand reflection and encountered one scenario where I couldn't really figure out the reason for the codes' behavior. Hopefully I receive some guidance from the community.
Following is my test model class & here, for every instantiation, I want to know the exact number of instances created during runtime (using reflection)
public final class Model {
private static final Model instance = new Model("Testing");
private static int count = 0;
private String name;
private Model(String name) {
this.name = name;
++count;
}
public static Model getInstance() {
return instance;
}
public static int getInstanceCount() {
return count;
}
public String getName() {
return name;
}
public void doSomething() {
try {
System.out.println("Shh.... I am trying to do something");
Thread.sleep(1000);
System.out.println("Ok! Done.");
return;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Oops! I failed in doing your job...");
}
}
The driver code for this scenario is as follows,
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Model.getInstance().doSomething();
System.out.println(Model.getInstanceCount());
Constructor<?>[] constructor = Model.class.getDeclaredConstructors();
for (Constructor<?> aConstructor : constructor) {
aConstructor.setAccessible(true);
Model m = (Model) aConstructor.newInstance("Testing through Reflection");
System.out.println(m.getName());
m.doSomething();
System.out.println(m.getInstanceCount());
//System.out.println(Model.getInstanceCount());
}
}
}
The output for this above piece of code came out to be as follows,
Shh.... I am trying to do something
Ok! Done.
0
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
1
As you can see, the instance count came out to be 1. I expected it to be as 2.
However, I changed the test model class's constructor as shown below. The datatype of count is now changed to Integer, instead of previously set 'int'.
private Model(String name) {
this.name = name;
if (count == null)
count = 0;
++count;
}
Surprisingly, I get the correct value for the instance count.
Shh.... I am trying to do something
Ok! Done.
1
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
2
This might be a silly question, but I am not able to ponder on what really happened behind the scenes. I need some guidance from the community on this.
Thanks in advance.
This has nothing to do with reflection.
private static final Model instance = new Model("Testing");
private static int count = 0;
The initializers are executed in order. So:
private static final Model instance = new Model("Testing");
Executing the constructor causes count to be incremented from 0 to 1, but then:
private static int count = 0;
Sets count back to zero.
Reverse the order of the declarations.
private static int count = 0;
private static final Model instance = new Model("Testing");
Or omit the initializer on count (its default value is zero anyway).
private static final Model instance = new Model("Testing");
private static int count;

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.

ThreadLocal<T> Documentation in JDK

JDK 1.6 documentation shows an example about how to use LocalThread<T>. I copy and paste it here:
For example, the class below generates unique identifiers local to each thread. A thread's id is assigned the first time it invokes UniqueThreadIdGenerator.getCurrentThreadId() and remains unchanged on subsequent calls.
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal <Integer> uniqueNum =
new ThreadLocal <Integer> () {
#Override
protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueId.get();
}
} // UniqueThreadIdGenerator
My problem is:
when multiple threads call UniqueThreadIdGenerator.getCurrentThreadId() it only returns 0 because there is no initialization. Shouldn't it be like this:
public static int getCurrentThreadId() {
return uniqueNum.get();
}
Now after the first call, it goes and initialize the variable.
Yes, it should be uniqueNum.get(). The JDK 7 docs get it right, and use better names:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
#Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}
It's not really a matter of initialization though - it's simply a matter of using the wrong member entirely. Even if lots of code had used uniqueNum in the original code, getCurrentThreadId() would always have returned "the next ID to be assigned" instead of "the ID assigned for the current thread".

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.

java - an enum question

I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx

Categories