Как вывести новую заработную плату отдела
Что нужно: вывести новую заработную плату отдела
Что не так: Нас здесь в целом интересует только класс 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 шт):
Мой вариант, по-быстрому, на идеальный не тянет, но проблему, как я понял - решает.
Для сокращения кода убрал проверки у 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);
}
Я решил доработать свою программу, сделав всё в одном цикле
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());
}
}
}
}