Reputation: 23
I have two classes: Car and LearnArrayList. Car is encapsulated class, having properties like: manufacturer,gearbox,ps,fuelType, static carID(PROBLEM WITH THIS VARIABLE). I put in Car constructor statement what increases carID by 1 (carID++). I have created such a code to learn arrayList:
public class LearnArrayList implements FutureFunctionality {
public static void main(String[] args) {
LearnArrayList learn = new LearnArrayList();
learn.createObjects();
learn.getInfo();
}
List<Car> listOfCars = new ArrayList();
public void createObjects() {
Car bmw = new Car("bmw", "mechanic", 200, "diesel");
Car ford = new Car("ford", "automatic", 150, "petrol");
Car vw = new Car("vw", "mechanic", 120, "petrol");
Car audi = new Car("audi", "mechanic", 100, "petrol");
Car mercedes = new Car("mercedes", "mechanic", 200, "diesel");
Car opel = new Car("opel", "automatic", 105, "petrol");
Car toyota = new Car("toyota", "mechanic", 103, "petrol");
Car renault = new Car("renault", "automatic", 100, "diesel");
Car dacia = new Car("dacia", "mechanic", 250, "petrol");
Car lada = new Car("lada", "mechanic", 80, "petrol");
Car[] cars = { bmw, ford, vw, audi, mercedes, opel, toyota, renault, dacia, lada };
for (int i = 0; i < cars.length; i++) {
addToArrayList(cars[i]);
}
}
@Override
public void addToArrayList(Car car) {
listOfCars.add(car);
}
@Override
public void getInfo() {
for (int i = 0; i < listOfCars.size(); i++) {
System.out.println(listOfCars.get(i).toString());
}
}
}
My output should be 10 records. I want to have an unique ID for each car, but the result when I run a program is always 10 for each car. I want to make that bmw is 1, ford is 2, vw is 3 and so on..
A little bit of Output:
Car ID: 10 Manufacturer: bmw GearBox: mechanic PS: 200 FuelType: diesel
Car ID: 10 Manufacturer: ford GearBox: automatic PS: 150 FuelType: petrol
Car ID: 10 Manufacturer: vw GearBox: mechanic PS: 120 FuelType: petrol
Car ID: 10 Manufacturer: audi GearBox: mechanic PS: 100 FuelType: petrol
Upvotes: 1
Views: 162
Reputation: 11
While @Mureinik's answer might seem to work, it's technically flawed and would be a bad habit to get into. Not only does will it allow for potentially duplicated Car Ids, but those sort of bugs can be difficult to find.
One additional thing to ensure proper multi-threaded behavior of CarId in Christopher Schultz's answer would be to add the "volatile" to ensure that the Java Virtual Machine properly treats it as a shared variable and ensures a consistent view of it's value to each thread.
Details about Java's field modifiers can be found here: Java Language Specification - Field Modifiers
Upvotes: 1
Reputation: 20837
To be absolutely safe, you need to use synchronization. @Mureinik's answer will probably work most of the time, but there are edge cases where multi-threaded accesses can be out of sync. In your "car" example, it doesn't matter. When controlling a self-driving car, the problem may be more serious.
The safest implementation of your Car class looks like this:
public class Car {
private static CarId = 0;
private static synchronized int nextCarId() { return CarId++ };
private int id;
public Car() {
this.id = nextCarId();
}
}
This will ensure that all threads always see the correct value for Car.CarId
and each Car
instance gets a unique value for its own id
member.
Upvotes: 2
Reputation: 4741
This is because the value of static field carId inside your Car class will be the same for every instace of Car class. You can create a static idCounter then increment and pass this value for a normal carId field. But this approach is not thread safe.
public class Car{
private static long m_idCounter = 0; // initial value
private long m_carId;
// .. other fields
public Car () {
this.m_carId = m_idCounter; // new id simulation
this.m_idCounter+=1; // id for next car instance. Same value for all instances of Car class.
//... do other stuffs
}
//... stuffs
}
Upvotes: 1
Reputation: 311073
Making the car id static
means that all the cars will share the id. Instead, you can have an instance member with the id, and keep a static counter for the next id. E.g.:
public class Car {
private static int nextId = 1;
private int id;
// Other data members...
public Car(/* arguemnts... */) {
id = nextId;
++nextId;
// Handle the other arguments and store them in data member
}
}
Upvotes: 3
Reputation: 7230
You should make carID
non-static and create a separate static variable to serve as the auto increment, like, say, nextCarID
. Then you can populate carID
via this.carID = nextCarID++;
.
Upvotes: 3