Проблема с корректным обновлением статической переменной по всем объектам - PullRequest
1 голос
/ 17 марта 2019

Я хочу иметь переменную, которая подсчитывает все количество сотрудников по всем созданным объектам в 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.Я должен выяснить, как правильно обновлять totalNumEmp после того, как dep1 указывает на ссылку dep2.Я знаю, что мог бы легко сделать dep1.setEmp(dep2.numEmp) и избежать его путаницы totalNumEmp, но я должен знать, как это сделать с dep1, указывающим на dep2.

Ответы [ 4 ]

0 голосов
/ 17 марта 2019

Проблема заключается в том, как вы структурировали свой код: вы изменяете значение totalNumEmp в установщике setEmp(), а статическое поле и установщик принадлежат одному и тому же классу.

Из-за этого следующее:

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

на самом деле выполнит установщик один раз (что, вероятно, то, что вы хотели), но totalNumEmp также будет изменен только один раз (и вы, кроме его, должны быть изменены дважды, для правильной установки totalNumEmp в 20).

Я бы порекомендовал изменить в вашем дизайне следующее:

  1. Храните totalNumEmp в отдельном классе или генерируйте его на лету.
  2. Не делайте этого, так как это плохая практика: dep1 = dep2. Вместо этого используйте копирующий конструктор (public Department(Department other)).
  3. Подумайте о параллелизме, например, рассмотрите возможность использования AtomicInteger вместо int или синхронизации.
0 голосов
/ 17 марта 2019

Избавьтесь от переменной 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();
}
0 голосов
/ 17 марта 2019

Отказ от ответственности: я сделаю все как можно проще.Нет необходимости инкапсуляции данных, шаблонов, параллелизма или чего-либо еще.Сохраняйте это как можно более простым при изучении основ.

Прежде всего, вам необходимо понять, что вы делаете.

наш учитель хочет, чтобы у нас была переменная, которая рассчитываетвсе количество сотрудников ...

Здесь я вижу класс Department с методом setEmp, который, по-видимому, увеличивает число сотрудников при каждом вызове.Я не думаю, что это то, что имел в виду ваш учитель

... во всех созданных объектах в main.

То, что ваш учитель, скорее всего, хочет, чтобы выУ do есть два класса (я полагаю, вы создали Department по причине):

Employee

, который назначен на

Department

Снова

... подсчитывает все количество сотрудников во всех созданных объектах в основном

Мы можем интерпретировать это двумя способами

  1. Ваш учитель хочетподсчитать все созданные Employee с (как следует из названия вопроса)
  2. Ваш учитель хочет, чтобы вы подсчитали все Employee с за Department

Давайте начнем сoption 1

Я пропущу класс Department, так как он на самом деле не входит в область действия, и я перейду непосредственно к созданному количеству сотрудников .
Что назначенная задача скажет, так это просто подсчитать созданные объекты, что означает созданные 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

Поскольку вам нужно считать 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;
}

Я не включал объекты или темы о синхронизации или параллелизме, так как я думаю, что вы все еще в начале и не должны путаться с этимвещи.

0 голосов
/ 17 марта 2019

System.out.println (dep1.totalNumEmp) печатает 30, потому что переменная totalNumEmp является статической в ​​отделе модели.

Почему вы хотите, чтобы общее количество сотрудников всех отделов в dep1.totalNumEmp?По моему мнению, вы не можете сохранить общую занятость всех отделов в одном экземпляре модели Отдела, потому что каждая модель должна содержать ваши собственные данные.

Чтобы подсчитать общее количество сотрудников, вы должны сделать что-то вроде:

Integer totalEmployees = dept1.totalNumEmp + dept2.totalNumEmp;

Obs: я рекомендую вам использовать шаблон Get для доступа к данным в моделях и не оставляйте приватные поля с "public"модификатор.Пример:

Integer totalEmployees = dept1.getTotalNumEmp() + dept2.getTotalNumEmp();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...