保持静态变量在整个对象中正确更新的问题

时间:2019-03-16 22:42:38

标签: java object static-variables

我想要一个变量,该变量计算main中所有已创建对象中所有雇员的数量。这是我的距离:

{% for category in categories %} .
    <a href="{{ category.get_absolute_url }}" class="nav">
        {{category}}
    </a>
{% endfor %}

我的问题是,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指向totalNumEmp的引用后才能正确更新dep1。我知道我可以轻松地做dep2并避免它弄乱dep1.setEmp(dep2.numEmp),但是我必须知道如何使用totalNumEmp指向dep1来做到这一点。

4 个答案:

答案 0 :(得分:0)

System.out.println(dep1.totalNumEmp)正在打印30,因为变量totalNumEmp在模型部门是静态的。

您为什么要让所有部门的员工总数为dep1.totalNumEmp?在我看来,您不能将所有部门的总雇员保留在一个部门模型实例中,因为每个模型都应包含您自己的数据。

要计算员工总数,您应该执行以下操作:

Integer totalEmployees = dept1.totalNumEmp + dept2.totalNumEmp;

肥胖:我建议您使用“获取”模式来访问模型中的数据,并且不要使用“ public”修饰符保留私有字段。 例如:

Integer totalEmployees = dept1.getTotalNumEmp() + dept2.getTotalNumEmp();

答案 1 :(得分:0)

除去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();
}

答案 2 :(得分:0)

免责声明:我会尽量简化。无需数据封装,模式,并发等。学习基础知识时,请使其尽可能简单。

首先,您需要了解自己在做什么。

  

我们的老师希望我们有一个可以计算所有数字的变量   员工...

在这里,我看到一个Department类和一个setEmp方法,这似乎增加了每次呼叫的员工人数。我认为这不是您的老师

的意思。
  

...贯穿main中所有已创建的对象。

您的老师最可能希望您做的是开设两节课(我假设您出于某种原因创建了Department

Employee

已分配给

Department

再次

  

...计算所有已创建员工的总数   主对象

我们可以用两种方式对此进行解释

  1. 您的老师希望您计算所有创建的Employee(如问题标题所示)
  2. 您的老师希望您对Employee中的所有Department进行计数

让我们从选项 1

开始

我将跳过Department类,因为它实际上不在范围内,我将直接转到创建的员工人数
分配的任务将只计算创建的对象,这意味着创建的Employee个。

这是Employee类的样子

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

由于您需要为每个Employee计算Department,因此需要在Department类内增加一种计数。这就是Department类的样子

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);
   }
}

您可以看到该类拥有

  • 一个名字
  • 已分配员工的列表(private final List<Employee> employees

然后,我们有一个Employee类,就像我上面描述的那样,但是要注意更改

public class Employee {
   // ... Class fields

   public Employee(
       final String name,
       final String surname) {
      // ... Assign arguments to class fields
   }

   ... 
}

在这里,我们只有一个普通的课程( Pojo )。我们如何使用它?遵循代码中的注释

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;
}

我没有包含有关同步或并发的对象或主题,因为我认为您仍处于起步阶段,不需要与这些东西混淆。

答案 3 :(得分:0)

问题在于代码的结构方式:您正在totalNumEmp设置程序中更改setEmp()的值,并且静态字段和设置程序都属于同一类。

因此,以下内容:

dep1 = dep2;     // here dep1 starts referencing dep2
dep1.setEmp(10);

实际上将执行一次setter(这可能是您想要的),但是totalNumEmp也将只更改一次(并且您将其更改两次,以将totalNumEmp正确设置为20)

我建议在您的设计中更改以下内容:

  1. totalNumEmp保留在单独的类中,或即时生成。
  2. 请勿执行此操作,因为这是错误的做法:dep1 = dep2。改用复制构造器(public Department(Department other))。
  3. 考虑并发性,例如考虑使用AtomicInteger而不是int或同步。