在整个对象中保持静态变量正确更新的问题
Issue with keeping a static variable correctly updated throughout objects
我想要一个变量来计算 main 中所有创建的对象中的所有员工人数。这是我的进度:
public class test {
public static void main(String[] args) {
Department dep1 = new Department();
Department dep2 = new Department("CSTI", 30);
dep1.setEmp(20);
dep2.setEmp(40);
System.out.println(dep1.totalNumEmp);
// Outputs 60
dep1 = dep2; // here is where I get lost
dep1.setEmp(10);
System.out.println(dep1.numEmp + " " + dep2.numEmp);// outputs 10 10
System.out.println(dep1.totalNumEmp);// Outputs 30. When it needs to output 20, because dep1 and dep2 are now
// both 10
}
}
class Department {
String name;
int numEmp;
public static int totalNumEmp;
Department() {
}
Department(String newName, int newNum) {
name = newName;
numEmp = newNum;
totalNumEmp += numEmp;
}
public void setEmp(int newNum) {
totalNumEmp -= numEmp;
numEmp = newNum;
totalNumEmp += numEmp;
}
}
我的问题是,我不知道如何让 totalNumEmp 正确更新一次 dep1 = dep2
。在 dep1
指向 dep2
的引用后,我必须想出一种方法来保持 totalNumEmp
正确更新。我知道我可以轻松地做到 dep1.setEmp(dep2.numEmp)
并避免它弄乱 totalNumEmp
,但我必须知道如何将 dep1
指向 dep2
。
System.out.println(dep1.totalNumEmp) 正在打印 30,因为变量 totalNumEmp 在模型部门是静态的。
为什么要让所有部门的员工总数在dep1.totalNumEmp?在我看来,您不能在 Department 模型的一个实例中保留所有部门的总雇员,因为每个模型都应该包含您自己的数据。
要计算员工总数,您应该像这样:
Integer totalEmployees = dept1.totalNumEmp + dept2.totalNumEmp;
Obs:我建议您使用 Get 模式访问模型中的数据,并且不要使用 "public" 修饰符保留私有字段。
例如:
Integer totalEmployees = dept1.getTotalNumEmp() + dept2.getTotalNumEmp();
去掉totalNumEmp变量,它没有用,在面向对象编程中不属于部门,因为它不是每个部门的属性。
在您的主体中,创建您部门的数组列表
ArrayList<Departments> allDepartments = new ArrayList<>();
allDepartments.add(dep1);
allDepartments.add(dep2);
//...
然后创建一个静态方法来计算您的员工总数:
private static int countTotalNum(ArrayList<Departments> allDepartments) {
AtomicInteger sum = new AtomicInteger();
allDepartments.forEach(department -> sum.addAndGet(department.numEmp));
return sum.get();
}
免责声明:我会让事情尽可能简单。不需要数据封装、模式、并发性或其他任何东西。在学习基础知识的同时保持尽可能简单。
首先,你需要明白你在做什么。
our teacher wants us to have a variable that counts all of the number
of employees...
我在这里看到一个 Department
class,带有一个 setEmp
方法,它似乎在每次调用时增加了员工的数量。我不认为这就是你的老师
的意思
...throughout all of the created objects in main.
你的老师最可能希望你做的是有两个 classes(我假设你创建 Department
是有原因的):
Employee
分配给
Department
再次
...counts all of the number of employees throughout all of the created
objects in main
我们可以用两种方式来解释这一点
- 您的老师希望您数出所有已创建的
Employee
(如问题标题所示)
- 你的老师要你数出每个
Department
的所有 Employee
让我们从选项 1
开始
我将跳过 Department
class,因为它实际上不在范围内,我将直接转到 创建的员工人数 。
分配的任务会说的只是统计创建的objects,也就是创建的Employee
s.
这是 Employee
class 的样子
public class Employee {
// Count of the created employees
public static int count = 0;
// ... Class fields
public Employee(
final Department department,
final String name,
final String surname) {
// ... Assign arguments to class fields
// A new employee has been created. Increment the counter!
++count;
}
...
}
这个静态字段
public static int count = 0;
每次创建新的 Employee
时 递增。
您将能够通过
访问它
final int total = Employee.count;
现在,选项 2
由于您需要为每个 Department
计算 Employee
秒,因此您需要在 Department
class 中增加一种计数。这是 Department
class 当时的样子
public class Department {
private final List<Employee> employees;
private final String name;
public Department(final String name) {
this.employees = new ArrayList<Employee>();
this.name = name;
}
public String getName() {
return name;
}
public List<Employee> getEmployees() {
return employees;
}
public int getEmployeeCount() {
return employees.size();
}
public void addEmployee(final Employee employee) {
employees.add(employee);
}
}
你可以看到这个class拥有
- 一个名字
- 分配的员工列表(
private final List<Employee> employees
)
然后,我们有 Employee
class,就像我上面描述的那样,但要注意变化
public class Employee {
// ... Class fields
public Employee(
final String name,
final String surname) {
// ... Assign arguments to class fields
}
...
}
这里我们只有一个普通的 class(Pojo)。我们怎么用它?关注 in-code 条评论
public static void main(final String[] args) {
final Department dep1 = new Department("dep1");
dep1.addEmployee(new Employee("Name1", "Surname1"));
dep1.addEmployee(new Employee("Name2", "Surname2"));
final Department dep2 = new Department("dep2");
dep2.addEmployee(new Employee("Name3", "Surname3"));
// Now we have two departments.
// We can retrieve the count of employees for each using
final int dep1Count = dep1.getEmployeeCount();
final int dep2Count = dep2.getEmployeeCount();
// And we can have the total
final int total = dep1Count + dep2Count;
}
我没有包括 objects 或有关同步或并发的主题,因为我认为您仍处于起步阶段,不需要与那些东西混淆。
问题在于您如何构建代码:您正在更改 setEmp()
setter 中 totalNumEmp
的值,静态字段和 setter 都属于同样的 class.
因此,以下内容:
dep1 = dep2; // here dep1 starts referencing dep2
dep1.setEmp(10);
实际上会执行 setter 一次(这可能是你想要的)但是 totalNumEmp
也只会被改变一次(你除了它被改变两次,以正确设置 totalNumEmp
到 20).
我建议您在设计中更改以下内容:
- 将
totalNumEmp
保存在单独的 class 中或即时生成。
- 不要这样做,因为这是不好的做法:
dep1 = dep2
。请改用复制构造函数 (public Department(Department other)
)。
- 考虑并发性,例如考虑使用
AtomicInteger
而不是 int
或同步。
我想要一个变量来计算 main 中所有创建的对象中的所有员工人数。这是我的进度:
public class test {
public static void main(String[] args) {
Department dep1 = new Department();
Department dep2 = new Department("CSTI", 30);
dep1.setEmp(20);
dep2.setEmp(40);
System.out.println(dep1.totalNumEmp);
// Outputs 60
dep1 = dep2; // here is where I get lost
dep1.setEmp(10);
System.out.println(dep1.numEmp + " " + dep2.numEmp);// outputs 10 10
System.out.println(dep1.totalNumEmp);// Outputs 30. When it needs to output 20, because dep1 and dep2 are now
// both 10
}
}
class Department {
String name;
int numEmp;
public static int totalNumEmp;
Department() {
}
Department(String newName, int newNum) {
name = newName;
numEmp = newNum;
totalNumEmp += numEmp;
}
public void setEmp(int newNum) {
totalNumEmp -= numEmp;
numEmp = newNum;
totalNumEmp += numEmp;
}
}
我的问题是,我不知道如何让 totalNumEmp 正确更新一次 dep1 = dep2
。在 dep1
指向 dep2
的引用后,我必须想出一种方法来保持 totalNumEmp
正确更新。我知道我可以轻松地做到 dep1.setEmp(dep2.numEmp)
并避免它弄乱 totalNumEmp
,但我必须知道如何将 dep1
指向 dep2
。
System.out.println(dep1.totalNumEmp) 正在打印 30,因为变量 totalNumEmp 在模型部门是静态的。
为什么要让所有部门的员工总数在dep1.totalNumEmp?在我看来,您不能在 Department 模型的一个实例中保留所有部门的总雇员,因为每个模型都应该包含您自己的数据。
要计算员工总数,您应该像这样:
Integer totalEmployees = dept1.totalNumEmp + dept2.totalNumEmp;
Obs:我建议您使用 Get 模式访问模型中的数据,并且不要使用 "public" 修饰符保留私有字段。 例如:
Integer totalEmployees = dept1.getTotalNumEmp() + dept2.getTotalNumEmp();
去掉totalNumEmp变量,它没有用,在面向对象编程中不属于部门,因为它不是每个部门的属性。
在您的主体中,创建您部门的数组列表
ArrayList<Departments> allDepartments = new ArrayList<>();
allDepartments.add(dep1);
allDepartments.add(dep2);
//...
然后创建一个静态方法来计算您的员工总数:
private static int countTotalNum(ArrayList<Departments> allDepartments) {
AtomicInteger sum = new AtomicInteger();
allDepartments.forEach(department -> sum.addAndGet(department.numEmp));
return sum.get();
}
免责声明:我会让事情尽可能简单。不需要数据封装、模式、并发性或其他任何东西。在学习基础知识的同时保持尽可能简单。
首先,你需要明白你在做什么。
our teacher wants us to have a variable that counts all of the number of employees...
我在这里看到一个 Department
class,带有一个 setEmp
方法,它似乎在每次调用时增加了员工的数量。我不认为这就是你的老师
...throughout all of the created objects in main.
你的老师最可能希望你做的是有两个 classes(我假设你创建 Department
是有原因的):
Employee
分配给
Department
再次
...counts all of the number of employees throughout all of the created objects in main
我们可以用两种方式来解释这一点
- 您的老师希望您数出所有已创建的
Employee
(如问题标题所示) - 你的老师要你数出每个
Department
的所有
Employee
让我们从选项 1
开始我将跳过 Department
class,因为它实际上不在范围内,我将直接转到 创建的员工人数 。
分配的任务会说的只是统计创建的objects,也就是创建的Employee
s.
这是 Employee
class 的样子
public class Employee {
// Count of the created employees
public static int count = 0;
// ... Class fields
public Employee(
final Department department,
final String name,
final String surname) {
// ... Assign arguments to class fields
// A new employee has been created. Increment the counter!
++count;
}
...
}
这个静态字段
public static int count = 0;
每次创建新的 Employee
时 递增。
您将能够通过
final int total = Employee.count;
现在,选项 2
由于您需要为每个 Department
计算 Employee
秒,因此您需要在 Department
class 中增加一种计数。这是 Department
class 当时的样子
public class Department {
private final List<Employee> employees;
private final String name;
public Department(final String name) {
this.employees = new ArrayList<Employee>();
this.name = name;
}
public String getName() {
return name;
}
public List<Employee> getEmployees() {
return employees;
}
public int getEmployeeCount() {
return employees.size();
}
public void addEmployee(final Employee employee) {
employees.add(employee);
}
}
你可以看到这个class拥有
- 一个名字
- 分配的员工列表(
private final List<Employee> employees
)
然后,我们有 Employee
class,就像我上面描述的那样,但要注意变化
public class Employee {
// ... Class fields
public Employee(
final String name,
final String surname) {
// ... Assign arguments to class fields
}
...
}
这里我们只有一个普通的 class(Pojo)。我们怎么用它?关注 in-code 条评论
public static void main(final String[] args) {
final Department dep1 = new Department("dep1");
dep1.addEmployee(new Employee("Name1", "Surname1"));
dep1.addEmployee(new Employee("Name2", "Surname2"));
final Department dep2 = new Department("dep2");
dep2.addEmployee(new Employee("Name3", "Surname3"));
// Now we have two departments.
// We can retrieve the count of employees for each using
final int dep1Count = dep1.getEmployeeCount();
final int dep2Count = dep2.getEmployeeCount();
// And we can have the total
final int total = dep1Count + dep2Count;
}
我没有包括 objects 或有关同步或并发的主题,因为我认为您仍处于起步阶段,不需要与那些东西混淆。
问题在于您如何构建代码:您正在更改 setEmp()
setter 中 totalNumEmp
的值,静态字段和 setter 都属于同样的 class.
因此,以下内容:
dep1 = dep2; // here dep1 starts referencing dep2
dep1.setEmp(10);
实际上会执行 setter 一次(这可能是你想要的)但是 totalNumEmp
也只会被改变一次(你除了它被改变两次,以正确设置 totalNumEmp
到 20).
我建议您在设计中更改以下内容:
- 将
totalNumEmp
保存在单独的 class 中或即时生成。 - 不要这样做,因为这是不好的做法:
dep1 = dep2
。请改用复制构造函数 (public Department(Department other)
)。 - 考虑并发性,例如考虑使用
AtomicInteger
而不是int
或同步。