我编写了一个包含三个相关类的Java程序;员工,客户和合同。在我的main方法中,我创建了一个包含所有3个类的各种实例的数组;
// Create Clients
Client Client1 = new Client(1, "Client 1", 0);
Client Client2 = new Client(2, "Client 2", 0);
// Create Array of Clients
Client[] clients = new Client[] {Client1, Client2};
// Create Contracts
Contract Contract1 = new Contract("Contract 1", 1, 850, 4, 0, 1, 0);
Contract Contract2 = new Contract("Contract 2", 2, 500, 4, 0, 1, 0);
Contract Contract3 = new Contract("Contract 3", 3, 1500, 3, 0, 1, 0);
// Create Array of Contracts
Contract[] contracts = new Contract[] {Contract1, Contract2, Contract3};
// Create Employees
Employee Employee1 = new Employee(1, "Bradley", 0);
Employee Employee2 = new Employee(2, "Patrick", 0);
Employee Employee3 = new Employee(3, "Erin", 0);
Employee Employee4 = new Employee(4, "Jim", 0);
Employee Employee5 = new Employee(5, "Fredrick", 0);
// Create Array of Employees
Employee[] employees = new Employee[] {Employee1, Employee2, Employee3, Employee4, Employee5};
我在Contract.Java中有一个名为assignContractToEmployeeWithLeastContracts的函数,它接受2个参数,一组雇员和合同。功能是:
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Assign to employee with minimum contracts
int minContract = Integer.MAX_VALUE;
Employee employeeWithMinContracts = null;
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
// swap min and employee if true
employeeWithMinContracts = employee;
minContract = employeeWithMinContracts.getCurrentlyAssignedContracts();
}
}
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
我遇到的问题是,我需要处理如果2名员工分配的合同数量相同(最小)的情况。如果发生这种情况,我该如何随意挑选一名员工?我已经尝试在foreach循环中实现种子但是不断破坏一切。
任何帮助,将不胜感激,
谢谢,B
如果您使用的是Java 8或更高版本,则可能更具可读性:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
Employee employeeWithMinContracts = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.findAny()
.get();
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
编辑
虽然上面解决方案中的findAny()
表现出明确的非确定性,即可以自由选择流中的任何元素,这使您无法控制元素被选择的可能性;您可能希望具有均匀分布的概率。如果是这种情况,请参阅下面的第二个解决方案:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Arrays.stream(employees)
.mapToInt(Employee::getCurrentlyAssignedContracts)
.min()
.getAsInt();
List<Employee> minEmployees = Arrays.stream(employees)
.filter(e->e.getCurrentlyAssignedContracts() == minContract)
.collect(Collectors.toList());
Random r = new Random();
Employee employeeWithMinContracts = minEmployees.get(r.nextInt(minEmployees.size()));
employeeWithMinContracts.assignContract(employeeWithMinContracts, contract);
}
如果您希望两个以上的员工共享相同数量的最低合同,那么您需要在其中随机选择。您可以通过列出最小合同并随机选择一个来完成此操作。
// Assign contract to employee with least contracts
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
// Find the employees with the minimum contracts
int minContract = Integer.MAX_VALUE;
List <Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
//add duplicates to the list
if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
// swap min and employee if true
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
}
}
//Randomly pick an employee from the group.
int random = (int)(Math.random() * employeesWithMinContracts.size() );
employeeWithMinContracts.assignContract(employeesWithMinContracts.get(random), contract);
}
如果我理解正确,在您的assignContractToEmployeeWithLeastContracts
方法中,如果合同数量相同,您希望将合同随机分配给其中一个员工。
因为目前您将把它分配给合同数量最少的第一个员工。
您的方法将成为这样:
public void assignContractToEmployeeWithLeastContracts(Employee[] employees, Contract contract) {
int minContract = Integer.MAX_VALUE;
List<Employee> employeesWithMinContracts = new ArrayList<Employee>();
for (Employee employee : employees) {
if (employee.getCurrentlyAssignedContracts() < minContract) {
employeesWithMinContracts.clear();
employeesWithMinContracts.add(employee);
minContract = employee.getCurrentlyAssignedContracts();
} else if (employee.getCurrentlyAssignedContracts() == minContract) {
employeesWithMinContracts.add(employee);
}
}
int randomIndex = (int)(Math.random() * employeesWithMinContracts.size());
employeesWithMinContracts.get(randomIndex).assignContract(contract);
}
我们将利用Math.random
返回[0,1]之间的值这一事实,从而随机找到我们的employeesWithMinContracts列表索引。
备注:
Employee
作为assignContract
方法的参数。因为这个方法已经被问到了Employee
。Contract1
成为contract1
Employee1
成为employee1
等等...