pkr*_*ish 106 java comparable comparator
我有一个对象列表,我需要在一个字段上排序,比如分数.在没有多想的情况下,我编写了一个实现Comparator的新类,它可以执行任务并且可以正常运行.
现在回过头来看,我想知道我是否应该让我的类实现Comparable,而不是创建一个实现Comparator的新类.分数是对象将被订购的唯一字段.
我做过什么可以接受的做法?
是正确的方法"首先让类实现Comparable(对于自然顺序),如果需要替代字段比较,那么创建一个实现Comparator的新类"?
如果上面的(2)为真,那么它是否意味着只有在具有类实现Comparable之后才应该实现Comparator?(假设我拥有原始课程).
Bal*_*usC 124
使用Comparable,如果要定义一个默认的(天然)排序问题的对象的行为,常见的做法是使用的技术或自然(数据库?)的对象标识符这一点.
使用Comparator如果要定义一个外部可控有序的行为,这可以覆盖默认排序行为.
Yis*_*hai 78
我会说一个对象应该实现Comparable,如果这是对类进行排序的明确自然方式,并且任何人都需要对类进行排序通常会想要这样做.
但是,如果排序是类的异常使用,或者排序仅对特定用例有意义,那么比较器是更好的选择.
换句话说,给定类名,是否可以比较排序,或者你是否必须求助于阅读javadoc?如果是后者,赔率是未来每一分拣用例将需要一个比较,在这点可比的实现可能的类的用户放慢,而不是加速它们.
Boz*_*zho 57
用途Comparable:
用途Comparator:
Comparable.Comparable)行为的行为时.Yas*_*ash 20
可比 -java.lang.Comparable: int compareTo(Object o1)
可比较的对象能够将自己与另一个对象进行比较.类本身必须实现java.lang.Comparable接口才能比较其实例.
only one sort sequence基于实例属性实现.EX:Person.id比较者 -java.util.Comparator: int compare(Object o1, Object o2)
比较器对象能够比较两个不同的对象.该类不是比较它的实例,而是比较其他类的实例.此比较器类必须实现java.util.Comparator接口.
many sort sequence根据实例属性实现和命名每个.EX:Person.id, Person.name, Person.age例:
public class Employee implements Comparable<Employee> {
private int id;
private String name;
private int age;
private long salary;
// Many sort sequences can be created with different names.
public static Comparator<Employee> NameComparator = new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getName().compareTo(e2.getName());
}
};
public static Comparator<Employee> idComparator = new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return Integer.valueOf(e1.getId()).compareTo(Integer.valueOf(e2.getId()));
}
};
public Employee() { }
public Employee(int id, String name, int age, long salary){
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
// setters and getters.
// Only one sort sequence can be created with in the class.
@Override
public int compareTo(Employee e) {
//return Integer.valueOf(this.id).compareTo(Integer.valueOf(e.id));
//return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
if (this.id > e.id) {
return 1;
}else if(this.id < e.id){
return -1;
}else {
return Character.toString(this.name.charAt(0)).compareToIgnoreCase(Character.toString(e.name.charAt(0)));
}
}
public static void main(String[] args) {
Employee e1 = new Employee(5, "Yash", 22, 1000);
Employee e2 = new Employee(8, "Tharun", 24, 25000);
List<Employee> list = new ArrayList<Employee>();
list.add(e1);
list.add(e2);
Collections.sort(list); // call @compareTo(o1)
Collections.sort(list, Employee.nameComparator); // call @compare (o1,o2)
Collections.sort(list, Employee.idComparator); // call @compare (o1,o2)
}
}
Run Code Online (Sandbox Code Playgroud)
对于Java 8 Lambda:Comparator参考我的帖子.
小智 10
比较同一类的实例时应使用Comparable.
比较器可用于比较不同类的实例.
Comparable由类实现,需要为其对象定义自然顺序.像String实现Comparable.
如果一个人想要一个不同的排序顺序,那么他可以实现比较器并定义自己比较两个实例的方式.
小智 9
比较器做了可比较的一切,再加上更多.
| | Comparable | Comparator ._______________________________________________________________________________ Is used to allow Collections.sort to work | yes | yes Can compare multiple fields | yes | yes Lives inside the class you’re comparing and serves | | as a “default” way to compare | yes | yes Can live outside the class you’re comparing | no | yes Can have multiple instances with different method names | no | yes Input arguments can be a list of | just Object| Any type Can use enums | no | yes
我发现使用比较器作为匿名类的最佳方法如下:
private static void sortAccountsByPriority(List<AccountRecord> accounts) {
Collections.sort(accounts, new Comparator<AccountRecord>() {
@Override
public int compare(AccountRecord a1, AccountRecord a2) {
return a1.getRank().compareTo(a2.getRank());
}
});
}
Run Code Online (Sandbox Code Playgroud)
您可以在计划排序的类中创建此类方法的多个版本.所以你可以:
sortAccountsByPriorityAndType
等等...
现在,您可以在任何地方使用这些排序方法并获得代码重用.这给了我一切可比的东西,加上更多...所以我认为没有任何理由可以使用比较.
我会说:
以下几点可以帮助您决定在哪些情况下应该使用 Comparable 以及在哪种 Comparator 中使用:
1) 代码可用性
2) 单与多排序标准
3) Arays.sort() 和 Collection.sort()
4) 作为 SortedMap 和 SortedSet 中的键
5)更多的类与灵活性
6) 类间比较
7) 自然秩序
有关更详细的文章,您可以参考何时使用可比较以及何时使用比较器
如果对象的排序需要基于自然顺序,则请使用Comparable,而如果需要对不同对象的属性进行排序,请使用Java中的Comparator。
可比和比较器之间的主要区别:
+------------------------------------------------------------------------------------+
¦ Comparable ¦ Comparator ¦
¦-----------------------------------------+------------------------------------------¦
¦ java.lang.Comparable ¦ java.util.Comparator ¦
¦-----------------------------------------+------------------------------------------¦
¦ int objOne.compareTo(objTwo) ¦ int compareTo(objOne, objTwo) ¦
¦-----------------------------------------+------------------------------------------¦
¦ Negative, if objOne < objTwo ¦ Same as Comparable ¦
¦ Zero, if objOne == objTwo ¦ ¦
¦ Positive, if objOne > objTwo ¦ ¦
¦-----------------------------------------+------------------------------------------¦
¦ You must modify the clas whose ¦ You build a class separate from to sort. ¦
¦ instances you want to sort. ¦ the class whose instances you want ¦
¦-----------------------------------------+------------------------------------------¦
¦ Only one sort sequemce can be created ¦ Many sort sequences can be created ¦
¦-----------------------------------------+------------------------------------------¦
¦ Implemented frequently in the API by: ¦ Meant to be implemented to sort ¦
¦ String, Wrapper classes, Date, Calandar ¦ instances of third-party classes. ¦
+------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您需要自然顺序排序 - 用户可比较 如果您需要自定义顺序排序 - 使用比较器
例子:
Class Employee{
private int id;
private String name;
private String department;
}
Run Code Online (Sandbox Code Playgroud)
自然顺序排序将基于 ID,因为它是唯一的,而自定义顺序排序将是名称和部门。
参考资料:
一个类什么时候应该是可比较的和/或比较器的?
http://javarevisited.blogspot.com/2011/06/comparator-and-comparable-in-java.html
| 归档时间: |
|
| 查看次数: |
105082 次 |
| 最近记录: |