Java之——利用Comparator接口对多个排序条件进行处理

本文介绍了一个雇员列表的排序需求及其实现方法。通过定义雇员类并实现Comparator接口,可以按照级别、工资和入职年份对雇员进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/56513205

一、需求

    假设现在有个如此的需求:需要对一个这样的雇员列表进行排序,排序规则如下:
    1、首先级别最高的排在前面,
    2、如果级别相等,那么按工资排序,工资高的排在前面,
    3、如果工资相当则按入职年数排序,入职时间最长的排在前面。

雇员对象包含级别、工资和入职年份,代码如下:

package com.lyz.sort.bean;

import java.io.Serializable;


/**
 * 雇员信息
 * @author liuyazhuang
 *
 */
public class Employee implements Serializable {

	private static final long serialVersionUID = 4775629632953317597L;
	  /**
     * ID
     */
    public int id;
    /**
     * 级别
     */
    public int level;
    /**
     * 工资
     */
    public int salary;
    /**
     * 入职年数
     */
    public int year;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public Employee(int id, int level, int salary, int year) {
        this.id = id;
        this.level = level;
        this.salary = salary;
        this.year = year;
    }
}

二、实现Comparator接口

这里我们实现Java.util.Comparator接口,用于对雇员列表进行排序,代码如下:

package com.lyz.sort;

import java.util.Comparator;

import com.lyz.sort.bean.Employee;

/**
 * 核心排序类
 * @author liuyazhuang
 *
 */
public class EmpComparator implements Comparator<Employee> {

	@Override
	public int compare(Employee employee1, Employee employee2) {
		  int cr = 0;
          //按级别降序排列
          int a = employee2.getLevel() - employee1.getLevel();
          if (a != 0) {
              cr = (a > 0) ? 3 : -1;
          } else {
              //按薪水降序排列
              a = employee2.getSalary() - employee1.getSalary();
              if (a != 0) {
                  cr = (a > 0) ? 2 : -2;
              } else {
                  //按入职年数降序排列
                  a = employee2.getYear() - employee1.getYear();
                  if (a != 0) {
                      cr = (a > 0) ? 1 : -3;
                  }
              }
          }
          return cr;
	}

}

三、验证排序结果

下面用一个单元测试,来验证排序结果是否正确

package com.lyz.sort.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.Test;

import com.lyz.sort.EmpComparator;
import com.lyz.sort.bean.Employee;

/**
 * 测试排序类
 * 
 * @author liuyazhuang
 *
 */
public class SortTest {
	@Test
	public void sortTest() throws Exception {
		List<Employee> employeeList = new ArrayList<Employee>() {
			{
				add(new Employee(1, 9, 10000, 10));
				add(new Employee(2, 9, 12000, 7));
				add(new Employee(3, 5, 10000, 12));
				add(new Employee(4, 5, 10000, 6));
				add(new Employee(5, 3, 5000, 3));
				add(new Employee(6, 1, 2500, 1));
				add(new Employee(7, 5, 8000, 10));
				add(new Employee(8, 3, 8000, 2));
				add(new Employee(9, 1, 3000, 5));
				add(new Employee(10, 1, 2500, 4));
				add(new Employee(11, 2, 2000, 4));
			}
		};
		Collections.sort(employeeList, new EmpComparator());
		System.out.println("ID\tLevel\tSalary\tYears");
		System.out.println("=============================");
		for (Employee employee : employeeList) {
			System.out.printf("%d\t%d\t%d\t%d\n", employee.getId(), employee.getLevel(), employee.getSalary(),
					employee.getYear());
		}
		System.out.println("=============================");
	}
}
运行结果:

四、附录

java.util.Comparator接口源代码

/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.util;

/**
 * A {@code Comparator} is used to compare two objects to determine their ordering with
 * respect to each other. On a given {@code Collection}, a {@code Comparator} can be used to
 * obtain a sorted {@code Collection} which is <i>totally ordered</i>. For a {@code Comparator}
 * to be <i>consistent with equals</i>, its {code #compare(Object, Object)}
 * method has to return zero for each pair of elements (a,b) where a.equals(b)
 * holds true. It is recommended that a {@code Comparator} implements
 * {@link java.io.Serializable}.
 *
 * @since 1.2
 */
public interface Comparator<T> {
    /**
     * Compares the two specified objects to determine their relative ordering. The ordering
     * implied by the return value of this method for all possible pairs of
     * {@code (lhs, rhs)} should form an <i>equivalence relation</i>.
     * This means that
     * <ul>
     * <li>{@code compare(a,a)} returns zero for all {@code a}</li>
     * <li>the sign of {@code compare(a,b)} must be the opposite of the sign of {@code
     * compare(b,a)} for all pairs of (a,b)</li>
     * <li>From {@code compare(a,b) > 0} and {@code compare(b,c) > 0} it must
     * follow {@code compare(a,c) > 0} for all possible combinations of {@code
     * (a,b,c)}</li>
     * </ul>
     *
     * @param lhs
     *            an {@code Object}.
     * @param rhs
     *            a second {@code Object} to compare with {@code lhs}.
     * @return an integer < 0 if {@code lhs} is less than {@code rhs}, 0 if they are
     *         equal, and > 0 if {@code lhs} is greater than {@code rhs}.
     * @throws ClassCastException
     *                if objects are not of the correct type.
     */
    public int compare(T lhs, T rhs);

    /**
     * Compares this {@code Comparator} with the specified {@code Object} and indicates whether they
     * are equal. In order to be equal, {@code object} must represent the same object
     * as this instance using a class-specific comparison.
     * <p>
     * A {@code Comparator} never needs to override this method, but may choose so for
     * performance reasons.
     *
     * @param object
     *            the {@code Object} to compare with this comparator.
     * @return boolean {@code true} if specified {@code Object} is the same as this
     *         {@code Object}, and {@code false} otherwise.
     * @see Object#hashCode
     * @see Object#equals
     */
    public boolean equals(Object object);
}

### Java 中使用 `Comparator.comparing` 对 `List<Map<String, Object>>` 排序 为了实现对 `List<Map<String, Object>>` 的排序操作,可以利用 `Comparator.comparing()` 方法来创建比较器。此方法允许指定用于提取键值的函数,并基于该键对应的值来进行排序。 下面是一个具体的例子,展示如何按照特定字段(假设为 "age" 字段)对列表中的映射对象进行升序排列: ```java import java.util.*; import java.util.stream.Collectors; public class SortExample { public static void main(String[] args) { // 创建一个包含多个 Map 的 List 集合 List<Map<String, Object>> list = Arrays.asList( new HashMap<>() {{ put("name", "Alice"); put("age", 30); }}, new HashMap<>() {{ put("name", "Bob"); put("age", 25); }}, new HashMap<>() {{ put("name", "Charlie"); put("age", 35); }} ); // 使用 Comparator.comparing() 和 map.get() 来获取要排序的关键字并执行排序 List<Map<String, Object>> sortedList = list.stream() .sorted(Comparator.comparing(o -> (Comparable) o.get("age"))) .collect(Collectors.toList()); System.out.println(sortedList); } } ``` 这段代码首先定义了一个由哈希表组成的列表,其中每个哈希表代表一个人的信息记录。接着通过流式 API 调用 `sorted()` 函数,并传入自定义的比较器逻辑——即根据 `"age"` 键所关联的对象大小决定顺序[^1]。 需要注意的是,在实际应用中应当确保所有目标键存在以及其对应的数据类型一致以便于正确比较;如果不确定,则可能需要额外处理异常情况或提供默认值。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰 河

可以吃鸡腿么?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值