我有一系列对象,我想以特定的方式排序
例如:
我的课程Employee
有一个属性departmentId
Employee
个departmentId
个对象的实例具有相同的List<Employee> employees
值
员工也有工资属性
所以我想要排序(John, 10000, A)
(Jane, 30000, A)
(Bill, 32000, A)
(Jim, 12000, B)
(Jake, 50000, B)
(James, 14000, C)
个对象,以便排序顺序如下:
薪水最低的员工首先在列表中,然后是按同一部门的薪水排序的所有其他员工。
然后,在该部门的最后一名员工之后,我希望下一个部门的员工薪水低于所有其他部门,其余的员工排序等。
例如。
ng-view
等
实现这一目标的最有效方法是什么?我想使代码尽可能紧凑和高效,而不是创建临时匿名类将它们添加到哈希映射(除非这是唯一有效的方法)。
注意:
我知道比较器和类似的等。
我的问题不在于如何实际排序(我知道实现比较器)但是如何有效地完成这样的代码,最好避免一堆临时匿名对象
另外:我没有使用Java 8,并希望使用简单的Java方法
更新
回应评论。我希望那个工资最低,然后是下一个最高等级的部门
答案 0 :(得分:2)
我个人使用Employee
类和Department
类,两者都会扩展Comparable<T>
接口以利用库功能。
以下是一个Department类的示例,该类具有名称和员工列表,这些列表在构造时进行排序。您可能希望对getEmployees()
上的列表进行浅层复制,以防止其他人更改其顺序:
class Department implements Comparable<Department> {
private List<Employee> employees;
private char name;
public Department(char name, List<Employee> employees) {
// avoid mutating original list
this.employees = new ArrayList<Employee>(employees);
this.name = name;
Collections.sort(this.employees);
}
@Override
public int compareTo(Department other) {
if (other == null) {
return 1;
}
// employees are sorted by salary within their department.
// all we need is to compare the lowest-salary employees
// from both departments
return this.employees.get(0).getSalary()
- other.employees.get(0).getSalary();
}
public List<Employee> getEmployees() {
return this.employees;
}
public char getName() {
return this.name;
}
}
现在Employee
类只需要使用薪水比较来实现compareTo(Employee other)
:
class Employee implements Comparable<Employee> {
private String name;
private int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Employee other) {
if (other == null) {
return 1;
}
return this.salary - other.salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}
}
这应该允许您在部门列表上使用Collections.sort
并获得正确的订单。这是一个完整的例子:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Fiddles {
static class Department implements Comparable<Department> {
private List<Employee> employees;
private char name;
public Department(char name, List<Employee> employees) {
// avoid mutating original list
this.employees = new ArrayList<Employee>(employees);
this.name = name;
Collections.sort(this.employees);
}
@Override
public int compareTo(Department other) {
if (other == null) {
return 1;
}
return this.employees.get(0).getSalary()
- other.employees.get(0).getSalary();
}
public List<Employee> getEmployees() {
return this.employees;
}
public char getName() {
return this.name;
}
}
static class Employee implements Comparable<Employee> {
private String name;
private int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Employee other) {
if (other == null) {
return 1;
}
return this.salary - other.salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}
}
public static void main(String args[]) {
final Department A = new Department('A', new ArrayList<Employee>() {
{
add(new Employee("John", 10000));
add(new Employee("Jane", 30000));
add(new Employee("Bill", 32000));
}
});
final Department B = new Department('B', new ArrayList<Employee>() {
{
add(new Employee("Jim", 12000));
add(new Employee("Jake", 50000));
}
});
final Department C = new Department('C', new ArrayList<Employee>() {
{
add(new Employee("James", 14000));
}
});
List<Department> departments = new ArrayList<Department>() {
{
add(A);
add(B);
add(C);
}
};
Collections.shuffle(departments);
Collections.sort(departments);
for (Department department : departments) {
for (Employee e : department.getEmployees()) {
System.out.println(String.format(
"Employee: %s, Salary: %d, department: %s",
e.getName(), e.getSalary(), department.getName()));
}
}
}
}
答案 1 :(得分:2)
我认为最简单的方法是:
Map
到该部门的最低工资。这需要在列表中扫描一次(O(n))。所以这是一个演示(编辑:操作现在封装在Employee
类中。但它的工作是相同的):
public class Employee {
private String name;
private int salary;
private String department;
/**
* Comparator - Note that it has a constructor that takes a department ranking
* list, which should be prepared in advance
*/
private static class DepartmentAndSalaryComparator implements Comparator<Employee>{
Map<String,Integer> departmentRanking;
public DepartmentAndSalaryComparator(Map<String,Integer> departmentRanking) {
this.departmentRanking = departmentRanking;
}
@Override
public int compare(Employee o1, Employee o2) {
// If employees belong to the same department, rank them by salary
if ( o1.department.equals(o2.department )) {
return o1.salary - o2.salary;
}
// Get the lowest salaries for the departments of the respective employees
int o1Rank = departmentRanking.get(o1.department);
int o2Rank = departmentRanking.get(o2.department);
if ( o1Rank == o2Rank ) {
return o1.department.compareTo(o2.department);
}
return o1Rank - o2Rank;
}
}
public Employee(String name, int salary, String department) {
this.name = name;
this.salary = salary;
this.department = department;
}
/**
* Creates a map of department id to minimum salary in that department
* from a given list of employees.
* This operation is O(n)
* @param employees List of employees for which to calculate map
* @return Map of department rankings
*/
private static Map<String,Integer> calculateDepartmentRanking( List<Employee> employees ) {
Map<String,Integer> rankings = new HashMap<>();
for ( Employee emp : employees ) {
Integer currMin = rankings.get(emp.department);
if ( currMin == null || currMin > emp.salary ) {
rankings.put(emp.department, emp.salary);
}
}
return rankings;
}
/**
* Static method to sort a list of employees by Department, then by Salary, where
* the order of department is based on the minimum salary in that department.
* This operation is O(n log n)
*
* @param employees The list of employees to sort
*/
public static void sortListBySalaryBasedDepartment( List<Employee> employees ) {
Collections.sort(employees, new DepartmentAndSalaryComparator(calculateDepartmentRanking(employees)));
}
@Override
public String toString() {
return String.format("Employee: name=%s, salary=%d, dept.=%s",
name,
salary,
department);
}
public static void main(String[] args) {
// Create example list and shuffle it to make sure it's not ordered
List<Employee> employees = Arrays.asList(
new Employee("Millie", 12000, "Accounts"),
new Employee("Morris", 21200, "Accounts"),
new Employee("Jerry", 22000, "Accounts"),
new Employee("Ellen", 17000, "Sales"),
new Employee("Sandy", 12500, "Technology"),
new Employee("Jack", 40000, "Technology")
);
Collections.shuffle(employees);
// Sort using the special comparator
Employee.sortListBySalaryBasedDepartment(employees);
for (Employee e : employees) {
System.out.println(e);
}
}
}
输出:
Employee: name=Millie, salary=12000, dept.=Accounts Employee: name=Morris, salary=21200, dept.=Accounts Employee: name=Jerry, salary=22000, dept.=Accounts Employee: name=Sandy, salary=12500, dept.=Technology Employee: name=Jack, salary=40000, dept.=Technology Employee: name=Ellen, salary=17000, dept.=Sales