此处将为大家介绍关于我可以在不实现Comparable的情况下使用Comparator吗?的详细内容,并且为您解答有关不实现serializable的原因的相关问题,此外,我们还将为您介绍关于Coll
此处将为大家介绍关于我可以在不实现Comparable的情况下使用Comparator吗?的详细内容,并且为您解答有关不实现serializable的原因的相关问题,此外,我们还将为您介绍关于Collections 用 Comparable&&Comparator 排序细节、Comparable与Comparator的比较与使用、Comparator与Comparable的应用、comparator和comparable的区别的有用信息。
本文目录一览:- 我可以在不实现Comparable的情况下使用Comparator吗?(不实现serializable的原因)
- Collections 用 Comparable&&Comparator 排序细节
- Comparable与Comparator的比较与使用
- Comparator与Comparable的应用
- comparator和comparable的区别
我可以在不实现Comparable的情况下使用Comparator吗?(不实现serializable的原因)
是否可以在不实现Comparable类的情况下使用Comparator?例如,如果我有以下内容:
MyClass { Comparator comp; OrderedListInheritance(Comparator c) { this.comp = c; }}
然后可以使用comp比较两个对象吗?如果是这样,我将如何去做?
谢谢…
答案1
小编典典你不用Comparable
。您使用Comparator
。
Comparable
是由对象实现的接口,用于指定它们与相同类型的其他对象的排序顺序。
Comparator
是一个通用接口,只需要两个对象并告诉您它们的排序顺序。因此,您可以执行以下操作:
public class Student { private final int id; private final String name; private final int age; public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; }}
与:
public class AgeComparator implements Comparator<Student> { public int compare(Student s1, Student s2) { if (s1.getAge() == s2.getAge()) { return 0; } else { return s1.getAge() < s2.getAge() ? -1 : 1; }}
和:
List<Student> students = new ArrayList<Student>();students.add(new Student(1, "bob", 15));students.add(new Student(2, "Jane", 14));students.add(new Student(3, "Gary", 16));SortedSet<Student> set1 = new TreeSet<Student>(new AgeComparator());set1.addAll(students);for (Student student : set1) { // age order}
Collections 用 Comparable&&Comparator 排序细节

在收集对象之后,对对象进行排序是常用的动作。不用亲自操作排序算法 Java.util. Collections 提供有 sort() 方法。由于必须有索引才能进行排序,因此 Collections 的 sort() 方法接受 List 操作对象。例如:
package coll_map;
import java.util.*;
public class SortDemo {
public static void main(String[] args) {
List nums=Arrays.asList(3,6,2,7,5,9,0);
Collections.sort(nums);
System.out.println(nums);
}
}
1. 操作 Comparable
package coll_map;
import java.util.*;
class Sort2 {
private String name;
private String ID;
private int balance;
Sort2(String name, String ID, int balance) {
this.name = name;
this.balance = balance;
this.ID = ID;
}
@Override
public String toString() {
return String.format("账户(%s,%s,%d)", name,ID,balance);
}
}
public class Account{
public static void main(String[] args) {
List accounts=Arrays.asList(
new Sort2("zhangsan","9958X",999),
new Sort2("lisi","8779g",577),
new Sort2("wanger","99098X",6988)
);
Collections.sort(accounts);
System.out.println(accounts);
}
}
抛错: java.lang.ClassCastException 是因为 Collections 的 sort 方法,不知道是根据 Account 的 name、ID 或 balance 进行排序。sort()方法要求被排序的对象必须操作 java.lang. Comparable 接口,这个接口有个 compareto()方法必须返回大于 0、等于 0 或小于 0 的数:
package coll_map;
import java.util.*;
class Sort2 implements Comparable<Sort2>{
private String name;
private String ID;
private int balance;
Sort2(String name, String ID, int balance) {
this.name = name;
this.balance = balance;
this.ID = ID;
}
@Override
public String toString() {
return String.format("账户(%s,%s,%d)", name,ID,balance);
}
@Override
public int compareTo(Sort2 o) {
// TODO 自动生成的方法存根
return this.balance-o.balance;//判断排序条件
}
}
public class Account{
public static void main(String[] args) {
List accounts=Arrays.asList(
new Sort2("zhangsan","9958X",999),
new Sort2("lisi","8779g",577),
new Sort2("wanger","99098X",6988)
);
Collections.sort(accounts);
System.out.println(accounts);
}
}
collections 的 sot()方法在取得 a 对象与 b 对象进行比较时,会先将 a 对象扮演(Cast)为 comparable(也因此若对象没操作 Comparable,将会抛出 Classcastexception),然后调用 a.compareto(b),如果 a 对象顺序上小于 b 对象则返回小于 0 的值,若顺序上相等则返回 0,若顺序上 a 大于 b 则返回大于 0 的值。因此,上面的范例,将会依余额从小到大排列账户对象。前面的 Sort 类中,可以直接对 Integer 进行排序,因为 Integer 就有操作 Comparable 接口。 2. 操作 Comparator String 有操作 Comparable:
package coll_map;
import java.util.*;
public class SortDemo {
public static void main(String[] args) {
List words=Arrays.asList("D","A","H","Y","E");
Collections.sort(words);
//如果只想用String的compareTo方法可以:words.sort(String::compareTo);
System.out.println(words);
}
}
但是如果有对象无法操作 Comparable、拿不到原始码或者不能修改原始码。 比如让 String 排序结果反过来,就算修改 String. Java 后重新编译为 String.clas 放回 rt jar 中,也只有这个的 JRE 可以用,这已经不是标准 API 了。继承 string 后再重新定义 compareto()也不可能,因为 String 声明为 final,不能被继承。 Collections 的 sort()方法有另一个重载版本,可接受 Java util. **Comparator 接口的操作对象,如果使用这个版本,排序方式将根据 Comparator 的 compare()定义来决定。** 例如:
package coll_map;
import java.util.*;
public class SortDemo {
public static void main(String[] args) {
List<String> words=Arrays.asList("D","A","H","Y","E");
Collections.sort(words,new StringSort());
System.out.println(words);
}
}
class StringSort implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
// TODO 自动生成的方法存根
return -o1.compareTo(o2);
}
}
Comparator 的 compare()会传入两个对象,如果 o1 顺序上小于 o2 则返回小于 0 的值,顺序相等则返回 0,顺序上 o1 大于 o2 则返回大于 0 的值。在这个范例中,由于 string 本身就是 Comparable,所以将 compareto()返回的值乘上 - 1,就可以调换排列顺序。
package coll_map;
import java.util.*;
public class SortDemo {
public static void main(String[] args) {
List<String> words=Arrays.asList("D","A","H","Y","E");
//Collections.sort(words,(o1,o2) ->-o1.compareTo(o2));利用Lambda语法
words.sort((o1,o2) ->-o1.compareTo(o2));//更简单利用Lambda语法
System.out.println(words);
}
}
在 Java 的规范中,与顺序有关的行为,通常要不对象本身是 Comparable,要不就是另行指定 Comparator 对象告知如何排序。 例如,如果想针对数组进行排序,可以使用 java.util.Arrays 的 sort()方法,如果查询 API 文件,会发现该方法针对对象排序时有两个版本:一个版本是你收集在数组中的对象必须是 Comparable()否则会抛出 Classcastexception ,另一个版本则可以传入 compa rato 指定排序方式.
Set 的操作类之一 java. util. TreeSet 不仅拥有收集不重复对象的能力,还可用红黑树方式排序收集的对象,条件就是收集的对象必须是 comparable(否则会抛出 Classcastexception)或者是在创建 TreeSet 时指定 Comparator 对象。 Queue 的操作类之一 java util. Priorityqueue 也是,收集至 Priorityqueue 的对象,会根据你指定的优先权来决定对象在队列中的序,优先权的告知,要不就是对象必须是 comparable(否则会抛出 Classcastexception)或者是创建 Priorityqueue 时指定 Comparator 对象。 如果有个 List 中某些索引处包括 null,现在让 null 排在最前头,之后依字符串的长度由大到小排序,这样重新定义 compare:
@Override
public int compare(String o1, String o2) {
if(o1==o2) {
return 0;
}
if(o1==null) {
return -1;
}
if(o2==null) {
return 1;
}
if(o1.length()==o2.length()) {
return 0;
}
if(o1.length()>o2.length()) {
return -1;
}
return 1;
}
当然其实可以利用高级语义 API:
package coll_map;
import java.util.*;
import static java.util.Comparator.*;
public class SortDemo {
public static void main(String[] args) {
List<String> words=Arrays.asList("D","A","H","Y","E");
words.sort(nullsFirst(reverseOrder));//高级语义
System.out.println(words);
}
}
reverseOrder()返回的 Comparator 会是 Comparable 对象上定义顺序的反序, nullsFirst 接受 Comparator,在其定义的顺序上加上让 null 排在最前面的规则。 可以看到 import static 适当的运用,可以让程序码表达出本身操作的意图相比以下程序代码来说清楚许多:
words.sort(Comparator.nullsFirst(Comparator.reverseOrder));
Conparator 上还有很多方法可以使用,例如 comparing 与 thenComparing 等方法,要运用这些方法,得了解更多 JDK8 的 Lambda 特性,例如位于 java.util.function 套件中的 Function 等接口的意义
Comparable与Comparator的比较与使用
一 概述
1.Comparable与Comparator使用背景
数值型数据(byte int short long float double)天生可对比大小,可排序,string实现了comparable接口也可以对比大小与排序,而自定义类多种多样,没有一个共有的可以用作排序的指标,因此需要在自定义类中手动建立对比的方法,出于这个目的,java提供了两个接口comparable与comparator。
2.集合排序
Collections.sort()底层排序依靠的是Arrays.sort(),而Arrays.sort()排序时采用的是冒泡法。
二 Comparable
需要对比大小的对象可以实现Comparable接口,实现其中的抽象方法,该抽象方法用来设定比较的方式。下面以一个示例进行说明:
1.实体类
package com.javase.collections.comparable;public class Student implements Comparable<student> {private String name;private int score;public Student() {super(); }public Student(String name, int score) {super();this.name = name;this.score = score; }public String getName() {return name; }public void setName(String name) {this.name = name; }public int getScore() {return score; }public void setScore(int score) {this.score = score; } @Overridepublic int compareTo(Student stu) {return this.score - stu.score;// 操作对象减去参数对象,升序排列,反之降序。 } }</student>
在compareTo()方法中,以属性score为排序指标,采用“this.score-stu.score”,最终结果以升序排列,反之降序。
2.测试类
package com.javase.collections.comparable;import java.util.ArrayList;import java.util.Collections;import java.util.List;import org.junit.Test;public class ComparableTest { @Testpublic void testComparable() { List<student> stus = new ArrayList<student>(); Student zhangsan = new Student("zhangsan", 100); Student lisi = new Student("lisi", 90); Student wanger = new Student("wanger", 95); stus.add(zhangsan); stus.add(lisi); stus.add(wanger); System.out.println("排序前");for (Student x : stus) { System.out.println(x.getName() + "::" + x.getScore()); } System.out.println("排序后"); Collections.sort(stus);for (Student x : stus) { System.out.println(x.getName() + "::" + x.getScore()); } } }</student></student>
输出:
三 Comparator
如果一个类在创建时未实现Comparable接口,希望在不修改源码的情况下对其对象进行排序,可以在调用排序方法时实现Comparator比较器接口,指定排序方法。下面以一个示例进行说明:
1.实体类
package com.javase.collections.comparator;public class Student {private String name;private int score;public Student() {super(); }public Student(String name, int score) {super();this.name = name;this.score = score; }public String getName() {return name; }public void setName(String name) {this.name = name; }public int getScore() {return score; }public void setScore(int score) {this.score = score; } }
2.测试类
package com.javase.collections.comparator;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;import org.junit.Test;public class ComparatorTest { @Testpublic void test() { List<student> stus = new ArrayList<student>(); Student zhangsan = new Student("zhangsan", 100); Student lisi = new Student("lisi", 90); Student wanger = new Student("wanger", 95); stus.add(zhangsan); stus.add(lisi); stus.add(wanger); System.out.println("排序前");for (Student x : stus) { System.out.println(x.getName() + "::" + x.getScore()); } System.out.println("-----------------------"); Collections.sort(stus, new Comparator<student>() { @Overridepublic int compare(Student stu01, Student stu02) {// return stu01.getScore() - stu02.getScore();//升序return stu02.getScore() - stu01.getScore();// 降序 } }); System.out.println("排序后");for (Student x : stus) { System.out.println(x.getName() + "::" + x.getScore()); } } }</student></student></student>
在compare(Student stu01, Student stu02)方法中,以属性score为排序指标,采用“stu01.score-stu02.score”,最终结果升序排列,反之降序。
输出:
以上就是Comparable与Comparator的比较与使用的详细内容,更多请关注php中文网其它相关文章!
Comparator与Comparable的应用
当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。
阅读过程中有任何问题,请联系egg:
邮箱:xtfggef@gmail.com 微博:http://weibo.com/xtfggef
如有转载,请说明出处:http://blog.csdn.net/zhangerqing
一、Comparator
强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sort或Arrays.sort。
接口方法:
- /**
- * @return o1小于、等于或大于o2,分别返回负整数、零或正整数。
- */
- int compare(Object o1, Object o2);
/**
* @return o1小于、等于或大于o2,分别返回负整数、零或正整数。
*/
int compare(Object o1, Object o2);
例子:
- import java.util.Arrays;
- import java.util.Comparator;
- public class SampleComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- return toInt(o1) - toInt(o2);
- }
- private int toInt(Object o) {
- String str = (String) o;
- str = str.replaceAll("一", "1");
- str = str.replaceAll("二", "2");
- str = str.replaceAll("三", "3");
- //
- return Integer.parseInt(str);
- }
- /**
- * 测试方法
- */
- public static void main(String[] args) {
- String[] array = new String[] { "一二", "三", "二" };
- Arrays.sort(array, new SampleComparator());
- for (int i = 0; i < array.length; i++) {
- System.out.println(array[i]);
- }
- }
- }
import java.util.Arrays;
import java.util.Comparator;
public class SampleComparator implements Comparator {
public int compare(Object o1, Object o2) {
return toInt(o1) - toInt(o2);
}
private int toInt(Object o) {
String str = (String) o;
str = str.replaceAll("一", "1");
str = str.replaceAll("二", "2");
str = str.replaceAll("三", "3");
//
return Integer.parseInt(str);
}
/**
* 测试方法
*/
public static void main(String[] args) {
String[] array = new String[] { "一二", "三", "二" };
Arrays.sort(array, new SampleComparator());
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
二、Comparable
强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。
接口方法:
- /**
- * @return 该对象小于、等于或大于指定对象o,分别返回负整数、零或正整数。
- */
- int compareTo(Object o);
/**
* @return 该对象小于、等于或大于指定对象o,分别返回负整数、零或正整数。
*/
int compareTo(Object o);
假设对象User,需要按年龄排序:
- public class User {
- private String id;
- private int age;
- public User(String id, int age) {
- this.id = id;
- this.age = age;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- }
public class User {
private String id;
private int age;
public User(String id, int age) {
this.id = id;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
改造后的对象:
- import java.util.Arrays;
- public class User implements Comparable {
- private String id;
- private int age;
- public User(String id, int age) {
- this.id = id;
- this.age = age;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public int compareTo(Object o) {
- return this.age - ((User) o).getAge();
- }
- /**
- * 测试方法
- */
- public static void main(String[] args) {
- User[] users = new User[] { new User("a", 30), new User("b", 20) };
- Arrays.sort(users);
- for (int i = 0; i < users.length; i++) {
- User user = users[i];
- System.out.println(user.getId() + " " + user.getAge());
- }
- }
- }
import java.util.Arrays;
public class User implements Comparable {
private String id;
private int age;
public User(String id, int age) {
this.id = id;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int compareTo(Object o) {
return this.age - ((User) o).getAge();
}
/**
* 测试方法
*/
public static void main(String[] args) {
User[] users = new User[] { new User("a", 30), new User("b", 20) };
Arrays.sort(users);
for (int i = 0; i < users.length; i++) {
User user = users[i];
System.out.println(user.getId() + " " + user.getAge());
}
}
}
三、Comparator和Comparable的区别
先看一下使用Comparator对User集合实现排序的方式:
- import java.util.Arrays;
- import java.util.Comparator;
- public class UserComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- return ((User) o1).getAge() - ((User) o2).getAge();
- }
- /**
- * 测试方法
- */
- public static void main(String[] args) {
- User[] users = new User[] { new User("a", 30), new User("b", 20) };
- Arrays.sort(users, new UserComparator());
- for (int i = 0; i < users.length; i++) {
- User user = users[i];
- System.out.println(user.getId() + " " + user.getAge());
- }
- }
- }
import java.util.Arrays;
import java.util.Comparator;
public class UserComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((User) o1).getAge() - ((User) o2).getAge();
}
/**
* 测试方法
*/
public static void main(String[] args) {
User[] users = new User[] { new User("a", 30), new User("b", 20) };
Arrays.sort(users, new UserComparator());
for (int i = 0; i < users.length; i++) {
User user = users[i];
System.out.println(user.getId() + " " + user.getAge());
}
}
}
一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
1、类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等
comparator和comparable的区别
Comparable java.lang 内比较器
传入一个对象,与自身进行比较,返回差值 正整数 0 负整数。
实现接口 :public interface Comparable<T>
接口定义的方法:public int compareto(T o);
举例:
private static class Student implements Comparable{ int id; private Student(int id){ this.id = id; } @Override public int compareto(Object o) { return this.id - ((Student)o).id; } } public void studentCompareto(){ Student s1 = new Student(10); Student s2 = new Student(20); int b = s1.compareto(s2); System.out.println(String.valueOf(b)); }
Comparator java.util 外比较器
传入两个对象,进行比较
实现接口:public interface Comparator<T>
接口定义的方法 int compare(T o1,T o2);
举例
private static class StudentCom1 implements Comparator<Student> { @Override public int compare(Student o1,Student o2) { return o1.id - o2.id; } } public void studentCompatator() { List<Student> students = new ArrayList<>(); Student student1 = new Student(10); students.add(student1); Student student2 = new Student(20); students.add(student2); Student student3 = new Student(15); students.add(student3); Collections.sort(students,new StudentCom1()); for (Student student : students) System.out.println(student.id); }
今天关于我可以在不实现Comparable的情况下使用Comparator吗?和不实现serializable的原因的分享就到这里,希望大家有所收获,若想了解更多关于Collections 用 Comparable&&Comparator 排序细节、Comparable与Comparator的比较与使用、Comparator与Comparable的应用、comparator和comparable的区别等相关知识,可以在本站进行查询。
本文标签: