Как вывести новую заработную плату отдела

Что нужно: вывести новую заработную плату отдела

Что не так: Нас здесь в целом интересует только класс transferToDepartment, но добавил всё, чтобы связь понятна была. Программа почти полностью работает, кроме вывода, если 1 человека выводим, то всё хорошо. Ошибка кроется, как я понимаю, в этих двух строках. Как мне достать у этих работников заработные платы, чтобы я мог их сохранять в коллекцию, а затем разделить и вывести? Не понимаю как мне перебрать employeeList.get(i) в одном цикле, какое условие должно быть, чтобы прочли до конца список сотрудников?

sum = sum.add(employeeList.get(i).getSalary()); // Прибавляем зп человека к зп отдела
                    sum = sum.divide(BigDecimal.valueOf(EmplSecond.size()), 2, RoundingMode.HALF_UP);

Текущий вывод программы:

Перевод из Второй в Первый сотрудника Сик. Средняя зп отдела была: 68334 Стала: 70213.
Перевод из Второй в Первый сотрудника Пик. Средняя зп отдела была: 68334 Стала: 70213.
Перевод из Второй в Первый сотрудника Миг. Средняя зп отдела была: 68334 Стала: 70213.

Должно быть:

Перевод из Второй в Первый сотрудника Сик. Средняя зп отдела была: 68334 Стала: 82000.
Перевод из Второй в Первый сотрудника Пик. Средняя зп отдела была: 68334 Стала: 90000.
Перевод из Второй в Первый сотрудника Миг. Средняя зп отдела была: 68334 Стала: 102000.

Сам код:

public class Task implements AutoCloseable {

    public static void main(String[] args) {

        if (args.length != 2) {
            System.out.println();
            return;
        }

        Map<String, Department> departments = read(args[0]);
        if (!departments.isEmpty()) {
            systemMessage("Выбрали корректные варианты");
            List<String> strList = transferToDepartment(departments);
            uploadToFile(strList, args[1]);
            systemMessage("Перевели из отдела в отдел");
        }
    }

    public static List<String> transferToDepartment(Map<String, Department> departments) {
        List<String> download = new ArrayList<>();
        BigDecimal sum = BigDecimal.ZERO;
        int i = 0;

        for (Department depFrom : departments.values()) {
            for (Department depTo : departments.values()) {
                if (depFrom.equals(depTo))
                    continue;
                List<Employee> employeeList = new ArrayList<>();
                if (depFrom.salaryAvg().compareTo(depTo.salaryAvg()) > 0) {
                    employeeList.addAll(
                            depFrom.getEmployeeList().stream()
                                    .filter(emp -> emp.getSalary().compareTo(depFrom.salaryAvg()) < 0
                                            && emp.getSalary().compareTo(depTo.salaryAvg()) > 0)
                                    .collect(Collectors.toList()));
                    // Берём лист с зп, одну зп прибавляем к отделу, у которого меньше средняя зп
                    // выясняем сколько работников в отделе, делим сумму на количество работников
                    // Результат сохраняем в newAvgSalary результат
                }
                if (depFrom.salaryAvg().compareTo(depTo.salaryAvg()) > 0) {
                    if (employeeList.size() == 0) continue; // Необходимо, если размер равен 0
                    List<Employee> EmplSecond = depFrom.getEmployeeList(); // создаём для
                    for (Employee empls : EmplSecond) { // Проходим, чтобы посчитать зп по отделу
                        sum = sum.add(empls.getSalary()); // Сохраняем информацию в sum
                    }
                    sum = sum.add(employeeList.get(i).getSalary()); // Прибавляем зп человека к зп отдела
                    sum = sum.divide(BigDecimal.valueOf(EmplSecond.size()), 2, RoundingMode.HALF_UP); // Делим сумму на работников
                    i++;
                    for (Employee employee : employeeList) {
                        System.out.println("Перевод из " + depFrom.getName() + " в " + depTo.getName() +
                                " сотрудника " + employee.getName() + ". Средняя зп отдела была: " +
                                depFrom.salaryAvg() + " Стала: " + sum);
                        download.add("Перевод из " + depFrom.getName() + " в " + depTo.getName() +
                                " сотрудника " + employee.getName());
                    }
                }
                if (depFrom.salaryAvg().compareTo(depTo.salaryAvg()) < 0) {
                    if (employeeList.size() == 0) continue; // Необходимо, если размер равен 0
                    List<Employee> EmplSecond = depTo.getEmployeeList(); // создаём для
                    sum = BigDecimal.ZERO;
                    i = 0;
                    for (Employee empls : EmplSecond) { // Проходим, чтобы посчитать зп по отделу
                        sum = sum.add(empls.getSalary()); // Сохраняем информацию в sum
                    }
                    sum = sum.add(employeeList.get(i).getSalary()); // Прибавляем зп человека к зп отдела
                    sum = sum.divide(BigDecimal.valueOf(EmplSecond.size()), 2, RoundingMode.HALF_UP); // Делим сумму на работников
                    for (Employee employee : employeeList) {
                        System.out.println("Перевод из " + depTo.getName() + " в " + depFrom.getName() +
                                " сотрудника " + employee.getName() + ". Средняя зп отдела была: " +
                                depTo.salaryAvg() + " Стала: " + sum);
                        download.add("Перевод из " + depTo.getName() + " в " + depTo.getName() +
                                " сотрудника " + employee.getName());
                    }
                    i++;
                }
            }
        }
        return download;
    }

    private static void uploadToFile(List<String> download, String path) {
        try (FileWriter writer = new FileWriter(path, false)) {
            for (String str : download) {
                writer.write(str + '\n');
            }
            System.out.println("Читаемый файл закрыт");
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }

    public static Map<String, Department> read(String path) {
        Map<String, Department> departments = new HashMap<>();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path), "CP1251")); br) {
            String line;
            while ((line = br.readLine()) != null) {
                if (check(line)) {
                    String[] strings = line.split("/");
                    Employee emp = new Employee(strings[0].trim(), new BigDecimal(strings[1].trim()));
                    if (!departments.containsKey(strings[2].trim())) {
                        departments.put(strings[2].trim(), new Department(strings[2]));
                    }
                    departments.get(strings[2]).addEmployee(emp);
                    System.out.println(strings[0] + " " + strings[1] + " " + strings[2] + " - корректна, обрабатываем");
                }
            }
            System.out.println("Читаемый файл закрыт");
        } catch (FileNotFoundException e) {
            System.out.println("Файл не был найден, проверьте путь");
        } catch (IOException e) {
            System.out.println("Ошибка чтения файла");
        }
        return departments;
    }

    private static boolean check(String line) {
        String regex = "[А-Яа-яЁёA-Za-z\\s]+";
        if (!(line = line.trim()).isEmpty()) {
            String[] strings = line.split("/");
            if (strings.length < 3) {
                System.out.println(line + " - неверный формат строки, ожидаем ФИО/10000.12/Департамент");
                return false;
            }
            if (!(strings[0].trim().matches(regex) && strings[2].trim().matches(regex))) {
                System.out.println(line + " - неверный формат ввода, нужно: Буквы/Цифры/Буквы");
                return false;
            }
            if (!strings[1].trim().matches("\\d+(\\.\\d{1,2})?")) {
                System.out.println(line + " - некорректный ввод цифр, знаков. Зарплата не может быть отрицательной");
                return false;
            }
            return true;
        }
        return false;
    }

    public static void systemMessage(String message) {
        System.out.println("-".repeat(message.length()));
        System.out.println(message);
        System.out.println("-".repeat(message.length()));
    }

    @Override
    public void close() {
        System.out.println("Читаемый файл закрыт");
    }
}

    private static boolean check(String line) {
        String regex = "[А-Яа-яЁёA-Za-z\\s]+";
        if (!(line = line.trim()).isEmpty()) {
            String[] strings = line.split("/");
            if (strings.length < 3) {
                System.out.println(line + " - неверный формат строки, ожидаем ФИО/10000.12/Департамент");
                return false;
            }
            if (!(strings[0].matches(regex) && strings[2].matches(regex))) {
                System.out.println(line + " - неверный формат ввода, нужно: Буквы/Цифры/Буквы");
                return false;
            }
            if (!strings[1].matches("\\d+(\\.\\d{1,2})?")) {
                System.out.println(line + " - некорректный ввод цифр, знаков. Зарплата не может быть отрицательной и иметь меньше 5 знаков");
                return false;
            }
            return true;
        }
        return false;
    }

    public static void systemMessage(String message) {
        int line = message.length();
        int i = 0;
        while (i <= line) {
            System.out.print("-");
            i++;
        }
        System.out.println();
        System.out.println(message);
        i = 0;
        while (i <= line) {
            System.out.print("-");
            i++;
        }
        System.out.println();
    }

    @Override
    public void close() {
        System.out.println("Читаемый файл закрыт");
    }
}

Ответы (2 шт):

Автор решения: dmtr

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

Для сокращения кода убрал проверки у Optional.

public static void main(String[] args) {
    Departament financeDepartment = new Departament("Finance");
    financeDepartment.addEmployee(new Employee("Ivan Ivanov", BigDecimal.valueOf(80000)));
    financeDepartment.addEmployee(new Employee("Petr Petrov", BigDecimal.valueOf(93500)));
    Departament legalDepartment = new Departament("Legal");
    legalDepartment.addEmployee(new Employee("Andrey Anfreyev", BigDecimal.valueOf(130000)));
    Departament headDepartment = new Departament("Head Office");
    headDepartment.addEmployee(new Employee("Alexey Alexseev", BigDecimal.valueOf(240000)));
    headDepartment.addEmployee(new Employee("Dmitry Dmitryev", BigDecimal.valueOf(280000)));
    List<Departament> departaments = new ArrayList<>() {{
        add(financeDepartment);
        add(legalDepartment);
        add(headDepartment);
    }};
    // Поиск "бедного" департамента
    Optional<Departament> poorDepartment = departaments.stream()
            .min(Comparator.comparing(Departament::salaryAvg));
    // Выводим его в консоль
    System.out.println(poorDepartment.get());
    // Ссылка на "богатый" департамент
    AtomicReference<Departament> richDepartment = new AtomicReference<>();
    // Поиск "богатого" сотрудника в богатом департаменте
    Optional<Employee> richEmployeeFromRichDepartment = departaments.stream()
            .max(Comparator.comparing(Departament::salaryAvg))
            .stream().peek(richDepartment::set)
            .map(Departament::getEmployeeList)
            .flatMap(Collection::stream)
            .max(Comparator.comparing(Employee::getSalary));
    // Перевод
    replaceEmployee(richDepartment.get(), poorDepartment.get(), richEmployeeFromRichDepartment.get());
    
    // После перевода
    System.out.println(richDepartment.get());
    System.out.println(poorDepartment.get());
}
private static void replaceEmployee(Departament from, Departament to, Employee employee) {
    from.getEmployeeList().remove(employee);
    to.getEmployeeList().add(employee);
}
→ Ссылка
Автор решения: Blacit

Я решил доработать свою программу, сделав всё в одном цикле

for (Department depFrom : departments.values()) {
            for (Department depTo : departments.values()) {
                if (depFrom.equals(depTo))
                    continue;
                if (depFrom.salaryAvg().compareTo(depTo.salaryAvg()) > 0) {
                    List<Employee> employeeList = depFrom.getEmployeeList().stream()
                            .filter(emp -> emp.getSalary().compareTo(depFrom.salaryAvg()) < 0
                                    && emp.getSalary().compareTo(depTo.salaryAvg()) > 0).collect(Collectors.toList());
                    for(Employee employee : employeeList) {
                        List<Employee> EmplSecond = depFrom.getEmployeeList();
                        BigDecimal totalSalFrom = depFrom.getTotalSalary(depFrom);
                        totalSalFrom = totalSalFrom.add(employee.getSalary());
                        totalSalFrom = totalSalFrom.divide(BigDecimal.valueOf(EmplSecond.size()), 2, RoundingMode.HALF_UP); // Не то кол-во сотрудников
                        System.out.println("Перевод из " + depFrom.getName() + " в " + depTo.getName() +
                                " сотрудника " + employee.getName() + ". Средняя зп отдела была: " +
                                depFrom.salaryAvg() + " Стала: " + totalSalFrom);
                        download.add("Перевод из " + depFrom.getName() + " в " + depTo.getName() +
                                " сотрудника " + employee.getName());
                    }
                }
            }
        }
→ Ссылка