Java 比较器在哪些方面优于可比较的?
“您将如何按id或名称对员工对象集合进行排序”。为此,我们可以使用两个接口,即,Java 比较器在哪些方面优于可比较的?,java,sorting,comparator,comparable,Java,Sorting,Comparator,Comparable,“您将如何按id或名称对员工对象集合进行排序”。为此,我们可以使用两个接口,即,Comparator和Comparable。 这似乎是一个常见的面试问题 但我看不出为什么我应该使用这两种方法对员工对象进行排序 我一直在思考comparator实现了Comparable无法实现的功能。 我知道,如果对象(比较的实例变量)具有自然顺序,那么compariable是正确的选择。 但是如果需要自定义排序(例如字符串长度),则可以编写一个比较器。 这里我要说的是,只有当客户希望按照其他标准对数据进行排序时
Comparator和Comparable。
这似乎是一个常见的面试问题
但我看不出为什么我应该使用这两种方法对员工对象进行排序
我一直在思考comparator
实现了Comparable
无法实现的功能。
我知道,如果对象(比较的实例变量)具有自然顺序,那么compariable
是正确的选择。
但是如果需要自定义排序(例如字符串长度),则可以编写一个比较器。
这里我要说的是,只有当客户希望按照其他标准对数据进行排序时,才需要使用comparator
。
例如,我将实现一个Employee类
,使用可比接口
按id
排序。
但是,如果客户机希望按字符串
(名称)对Employee对象进行排序,他将实现comparator
作为一个具体类或匿名排序。
这里有我遗漏的东西吗
例如,在下面的代码中,对于Person对象,my compareTo方法比较年龄并对其排序
在compare方法中,我使用字符串长度(人名)进行排序。理论上,我可以在下面实现的compareTo方法中实现这两个功能
最后,与其他方法相比,下列方法是否有任何额外的好处
我以两种方式实现了comparator
1.作为一种静态方法,它被注释掉了
2.作为被注释掉的主方法中的匿名对象(?)
3.创建一个实现comparator的新类,并在collections.sort()中调用该类的实例——我在这里没有这样做
(The commented-out parts of the code works. They are just different implementations)
mport java.util.Collections;
import java.util.Comparator;
import java.util.*;
public class PersonComparator implements Comparable{
private String name;
private int age;
public PersonComparator(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "name=" + name + ", age=" + age;
}
/*@Override
public int compareTo(Object obj) {
if (!(obj instanceof PersonComparator)) {
throw new ClassCastException("Invalid object");
}
PersonComparator p2 = (PersonComparator)obj;
return this.age-p2.age;
}*/
/*Alternative CompareTo that checks for both age and name*/
public int compareTo(Object obj) {
if (!(obj instanceof PersonComparator)) {
throw new ClassCastException("Invalid object");
}
PersonComparator p2 = (PersonComparator)obj;
if (this.age!=p2.age){
return this.age-p2.age;
}
else {
return (this.name.length()-p2.name.length());
}
}
/*public static Comparator nameLengthComparator
= new Comparator() {
@Override
public int compare(Object obj1, Object obj2) {
if (!(obj1 instanceof PersonComparator) || !(obj2 instanceof PersonComparator)){
throw new ClassCastException("Invalid object");
}
else {
PersonComparator p1 = (PersonComparator)obj1;
PersonComparator p2 = (PersonComparator)obj2;
return p1.name.length()-p2.name.length();
}
}
};*/
public static void main(String[] args){
PersonComparator p1 = new PersonComparator("Alexander", 45);
PersonComparator p2 = new PersonComparator("Pat", 27);
PersonComparator p3 = new PersonComparator("Zacky", 45);
PersonComparator p4 = new PersonComparator("Rake", 34);
List<PersonComparator> list = new ArrayList<PersonComparator>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
System.out.println("Before sorting "+ list);
Collections.sort(list);
//System.out.println("After sorting by age "+ list);
//System.out.println("Before sorting "+ list);
//Collections.sort(list, nameLengthComparator);
System.out.println("After sorting by name length "+ list);
/*Collections.sort(list, new Comparator<PersonComparator>() {
@Override
public int compare(PersonComparator p1, PersonComparator p2) {
return p1.name.length()-p2.name.length();
}
}
);*/
System.out.println("After sorting by name length "+ list);
}
}
(注释掉的代码部分有效。它们只是不同的实现)
mport java.util.Collections;
导入java.util.Comparator;
导入java.util.*;
公共类PersonComparator实现可比较的{
私有字符串名称;
私人互联网;
公共人员比较程序(字符串名称,整数){
this.name=名称;
这个。年龄=年龄;
}
@凌驾
公共字符串toString(){
返回“name=“+name+”,age=“+age;
}
/*@凌驾
公共整数比较(对象对象对象){
if(!(个人比较程序的obj实例)){
抛出新的ClassCastException(“无效对象”);
}
个人比较者p2=(个人比较者)obj;
返回this.age-p2.age;
}*/
/*检查年龄和姓名的替代比较*/
公共整数比较(对象对象对象){
if(!(个人比较程序的obj实例)){
抛出新的ClassCastException(“无效对象”);
}
个人比较者p2=(个人比较者)obj;
if(this.age!=p2.age){
返回this.age-p2.age;
}
否则{
返回(this.name.length()-p2.name.length());
}
}
/*公共静态比较器名称长度比较器
=新的比较器(){
@凌驾
公共整数比较(对象obj1、对象obj2){
if(!(PersonComparator的obj1实例)| |!(PersonComparator的obj2实例)){
抛出新的ClassCastException(“无效对象”);
}
否则{
个人压缩机p1=(个人压缩机)obj1;
PersonComparator p2=(PersonComparator)obj2;
返回p1.name.length()-p2.name.length();
}
}
};*/
公共静态void main(字符串[]args){
PersonComparator p1=新的PersonComparator(“亚历山大”,45岁);
个人比较者p2=新的个人比较者(“Pat”,27);
PersonComparator p3=新的PersonComparator(“Zacky”,45);
PersonComparator p4=新PersonComparator(“Rake”,34);
列表=新的ArrayList();
列表。添加(p1);
列表。添加(p2);
列表。添加(p3);
列表。添加(p4);
System.out.println(“排序前”+列表);
集合。排序(列表);
//System.out.println(“按年龄排序后”+列表);
//System.out.println(“排序前”+列表);
//Collections.sort(list,namelingthcomparator);
System.out.println(“按名称长度排序后”+列表);
/*Collections.sort(list,newcomparator(){
@凌驾
公共整数比较(PersonComparator p1、PersonComparator p2){
返回p1.name.length()-p2.name.length();
}
}
);*/
System.out.println(“按名称长度排序后”+列表);
}
}
谢谢
比较器在哪些方面优于可比较的
它不是“优越的”。只是这两个接口以不同的方式(大致)做着相同的事情。在可比较的
情况下,排序逻辑在被排序的对象中。在比较器
情况下,逻辑与所声明的对象位于不同的类中
但我看不出为什么我应该使用这两种方法对员工对象进行排序
如果您需要能够将对象排序为不同的顺序,那么使用这两种方法是有意义的。然后可以将相关类声明为实现“自然”顺序的Comparable
,并使用Comparator
对象实现其他顺序
顺便说一下,比较器可能不应该实现compariable
,反之亦然
如果比较器实现了Comparable
,这意味着您正试图对比较器对象本身的实例进行排序
您的PersonComparator
类名称错误。它真的应该被称为Person
您能在回答中澄清一件事吗?我们已经从对象类中获得了
equals()
方法,那么为什么Comparator
接口再次促进了equals()
方法
有几点:
- 您似乎仍然混淆了
和Comparable
的用途。Comparator
对象上的比较器
方法等于
Collections.sort(list);
public class Person { String name; public Person(String name) { this.name = name; } public String getName() { return name; } }
class StrategyOne implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p1.getName().length() - p2.getName().length(); } } class StrategyTwo implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p1.getName().compareTo(p2.getName()); } }
class Strategies { private static final Comparator<Person> PERSON_NAME_LENGTH_COMPARATOR = new StrategyOne(); private static final Comparator<Person> PERSON_NAME_LEXICAL_COMPARATOR = new StrategyTwo(); public static Comparator<Person> personNameLengthComparator(){ return PERSON_NAME_LENGTH_COMPARATOR; } public static Comparator<Person> personNameLexicalComparator(){ return PERSON_NAME_LEXICAL_COMPARATOR; } }
class Person implements Comparable { int age; String name; Person(int age,String name) { this.age=age; this.name=name; } public int compareTo(Object o1) // Either you can compare according to age or name { Person p = (Person)o1; if (this.age==p.age) return 0; else if (this.age>p.age) return 1; else return -1; } public int compareTo(Object o) //Based on name comparision { return (this.name.compareTo((Person)o).name)); } public static void main (String args[]) { List<Person> list = new ArrayList<Person>(); Person o = new Person(12,"Steve"); Person o1 = new Person(13,"Jason"); list.add(o); list.add(o1); Collections.sort(list); } }
class AgeComparison implements Comparator { public int compare(Object o1,Object o2) { Person s1 = (Person)o1; Person s2 =(Person)o2; if (s1.age==s2.age) return 0; if(s1.age>s2.age) return 1; else return -1; } class NameComparison implements Comparator { public int compare(Object o1,Object o2) { Person s1 = (Person)o1; Person s2 =(Person)o2; return (s1.age.compareTo(s2.age)); } }
Collections.sort(list,new NameComparison()); Collections.sort(list,new AgeComparison());