【问题标题】:Implementing a Comparator with a specific condition实现具有特定条件的比较器
【发布时间】:2014-01-09 05:07:00
【问题描述】:

我需要实现 Comparator 以根据特定条件对 Employee 对象进行排序。

 class Employee
 {
      int employeeId;
      String employeeName;

 }

所以我手里已经有一个 List 的排序列表,我将排序顺序修改如下

  1. 保持排序顺序
  2. 如果 Employee 对象中的employeeName 是“Rock Hudson”,请将其添加到列表顶部。

>输入:

1 艾伦边境

2 贝蒂·爱德华兹

3 洛克哈德森

4 昆汀·塔伦蒂诺

5 伍迪艾伦

>输出

3 洛克哈德森

1 艾伦边境

2 贝蒂·爱德华兹

4 昆汀·塔伦蒂诺

5 伍迪艾伦

【问题讨论】:

标签: java sorting comparator


【解决方案1】:

你可以这样做

public static class Employee {
  // a constructor
  public Employee(int id, String name) {
    this.employeeId = id;
    this.employeeName = name;
  }

  // should be private and use getters and setters.
  int employeeId;
  String employeeName;

  // A special Comparator
  public static Comparator<Employee> rockHudsonComparator = new Comparator<Employee>() {
    @Override
    public int compare(Employee a, Employee b) {
      if (a.employeeName.equals("Rock Hudson")) {
        if (b.employeeName.equals("Rock Hudson")) {
          return 0;
        }
        return -1;
      } else if (b.employeeName.equals("Rock Hudson")) {
        return 1;
      }
      return a.employeeName
          .compareTo(b.employeeName);
    }
  };

  public String toString() {
    return "" + employeeId + " " + employeeName;
  }
}

public static void main(String[] args) {
  java.util.List<Employee> al = new java.util.ArrayList<Employee>();
  al.add(new Employee(1, "Alan Border"));
  al.add(new Employee(2, "Betty Edwards"));
  al.add(new Employee(3, "Rock Hudson"));
  al.add(new Employee(4, "Quentin Tarantino"));
  al.add(new Employee(5, "Woody Allen"));
  al.add(new Employee(6, "Rock Hudson")); // check the sort is stable.
  System.out.println("Before sort");
  System.out.println(al);
  java.util.Collections.sort(al,
      Employee.rockHudsonComparator);
  System.out.println("After sort");
  System.out.println(al);
}

哪些输出

[1 Alan Border, 2 Betty Edwards, 3 Rock Hudson, 4 Quentin Tarantino, 5 Woody Allen, 6 Rock Hudson]
[3 Rock Hudson, 6 Rock Hudson, 1 Alan Border, 2 Betty Edwards, 4 Quentin Tarantino, 5 Woody Allen]

【讨论】:

  • 感谢这项工作。我对此很陌生..如果我有多个首选元素..例如,如果我想将 Rock Hudson 和 Woody Allen 都移到顶部?
  • 你不应该让它们相等......因为如果你每个都有 3 个(例如),它会显得随机。但是您可以添加|| 并自己查看if (a.employeeName.equals("Rock Hudson") || a.employeeName.equals("Woody Allen")) {
  • 你看我说的了吗?没有员工同时拥有两个姓名,因此不能是and
  • 不要使用||。更加灵活。给Comparator 一个类型为Set&lt;String&gt; 的字段并使用contains。并且不要忘记确定“特殊”人出现的顺序。
【解决方案2】:
public class MyEmployeeComparator implements Comparator<Employee> {

    private final String alwaysTopEmployee;

    public MyEmployeeComparator(final String alwaysTopEmployee) {
        this.alwaysTopEmployee = alwaysTopEmployee;
    }

    @Override
    public int compare(Employee o1, Employee o2) {
        if (o2.getName().equals(alwaysTopEmployee) && o1.getName().equals(alwaysTopEmployee))
            return 0;
        if (o1.getName().equals(alwaysTopEmployee))
            return -1;
        if (o2.getName().equals(alwaysTopEmployee))
            return 1;

        return o1.getName().compareTo(o2.getName());
    }
}

然后调用:

Collections.sort(stuff, new MyEmployeeComparator("Rock Hudson"));

【讨论】:

    【解决方案3】:

    针对这种情况,只需在每个方向上测试一个特殊条件:

    Comparator<Employee> c = new Comparator<Employee>() {
        public int compare(Employee a, Employer b) {
            if (a.getName().equals("Rock Hudson"))
                 return -1;
            if (b.getName().equals("Rock Hudson"))
                 return 1;
            return a.getName().compareTo(b.getName());
        }
    }
    

    【讨论】:

    • @DavidWallace 我没有。我在开车时在我的iphone上输入了它。错误在哪里(对我来说看起来不错)?顺便说一句,我有意识地认为有 两个 Rock Hudsons 的极端情况是无关紧要的
    • 您似乎已经找到了主要错误并修复了它。还有不遵守Comparator的总合同的小问题(见我对别人回答的评论);但至少这会奏效。顺便说一句,我的家人(但不是我)目前正在墨尔本度假。您是否认为您可以在开车时避免回答 SO 问题,至少在他们回来之前? :-)
    • @ElliottFrisch 不再是了...... Muhahaha。但肯定是打错了。
    • @DavidWallace 没有碰撞危险:我在高峰时段在“高速公路”上 :)
    猜你喜欢
    • 2012-04-27
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2019-06-10
    • 2022-11-12
    • 2022-11-16
    相关资源
    最近更新 更多