黑马程序员技术交流社区
标题: TreeSet集合? [打印本页]
作者: 邵景伦 时间: 2014-4-16 10:59
标题: TreeSet集合?
使用TreeSet集合比较Comparable接口和Comparator接口的区别?所要覆盖i的方法不是多懂,求指点。
作者: ^o(孤8o|狼i¤F 时间: 2014-4-16 11:03
ThreeSet能够对集合中的对象排序,当TreeSet想集合中加入一个对象时,会把它插入到有序的对象序列中。那么TreeSet是如何排序呢?TreeSet支持两种排序方式:自然排序和客户化排序.在默认情况下TreeSet采用自然排序方式。
先来介绍介绍什么是自然排序吧
1、自然排序
在JDK类库中,有一部分类实现了Comparable接口,如Integer Double和String等。
Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y.TreeSet集合调用对象的compareTo()方法比较集合中的大小,注意鸟 不是TreeSet调用它自己的comparTo()方法而是它调用集合中对象的comparTo()方法.TreeSet类本身并没有实现Comparable接口,然后进行升序排列,这种方式称为自然排序.
有人可能要问TreeSet集合怎么给对象排序的按对象的什么排序的?
下面简单总结一哈
JDK类库中实现了Comparable接口的一些类的排序方式
类 BigDecimal BigInteger Byte Double Float Integer Long Short 排序方式是 按数字大小排序
类 Character是 按字符的Unicode值的数字大小排序
类 String是 按字符中字符的Unicode值排序
这里一定要灰常注意:使用自然排序时只能向集合中加入同类型的对象,并且这些对象的类必须实现Comparable接口
下面来说说Comparable接口和Comparator接口的区别
Comparator位于包java.util下,而Comparable位于包 java.lang下
Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口) 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
比如你有一个Customer类 想让这个类的实例加入集合后自动就具有某种排序功能只要这些实例加入集合后 就会按照你给Customer对象设定的方式排序
代码:
Java代码
package hang.jihe;
import java.util.HashSet;
import java.util.Set;
public class Customer implements Comparable {
private String name;
private int age;
public Customer(String name, int age) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Customer))
return false;
final Customer other = (Customer) obj;
if (this.name.equals(other.getName()) && this.age == other.getAge())
return true;
else
return false;
}
public static void main(String[] args) {
Set<Customer> set = new HashSet<Customer>();
Customer customer1 = new Customer("Tom", 15);
Customer customer2 = new Customer("Tom", 15);
set.add(customer1);
set.add(customer2);
System.out.println(set.size());
}
public int compareTo(Object o) {
Customer other = (Customer) o;
// 先按照name属性排序
if (this.name.compareTo(other.getName()) > 0)
return 1;
if (this.name.compareTo(other.getName()) < 0)
return -1;
// 在按照age属性排序
if (this.age > other.getAge())
return 1;
if (this.age < other.getAge())
return -1;
return 0;
}
@Override
public int hashCode() {
int result;
result = (name == null ? 0 : name.hashCode());
result = 29 * result + age;
return result;
}
}
main方法的类
Java代码
package hang.jihe;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class CustomerTester {
public static void main(String[] args) {
Set<Customer> set = new TreeSet<Customer>();
set.add(new Customer("Tom",15));
set.add(new Customer("Tom",20));
set.add(new Customer("Tom",15));
set.add(new Customer("Mike",15));
Iterator<Customer> it = set.iterator();
while(it.hasNext()){
Customer customer = it.next();
System.out.println(customer.getName()+" "+customer.getAge());
}
}
}
Java代码
//打印结果
Mike 15
Tom 15
Tom 20
作者: 杨庆雷 时间: 2014-4-16 11:37
上面的大哥介绍了comoparable 我来说一下Comparator TreeSet的两种排序方式(1). 让元素本身具有比较性
元素本身要实现Comparable接口并实现里面的compareTo方法以保证元素本身具有比较性
(2). 让容器自身具有比较性
当元素本身不具有比较性或者具备的比较性不是所需要的,就在TreeSet建立实例的时候,传入Comparator接口的实现子类的实例。这个Comparator子类必须实现compare方法。
【比较优先级】当元素和容器本身都具有比较性的时候,容器比较器优先
下面代码 对学生进行排序 先按照姓名排序 姓名一样在按照年龄排序
- class MyComparator implements Comparator{
- public int compare(Object o1, Object o2){
- if(!((o1 instanceof Student)&&(o2 instanceof Student))){
- throw new RuntimeException("类型不匹配");
- }
- Students1 =(Student)o1;
- Students2 =(Student)o2;
-
- int num =s1.getName().compareTo(s2.getName());
- if(num ==0)
- return s1.getAge() -s2.getAge();
- return num;
- }
- }
-
- class TreeSetDemoII{
- public static void sop(Object o){
- System.out.println(o);
- }
-
- public static void main(String[] args){
- TreeSetts =new TreeSet(new MyComparator());
- ts.add(new Student("lisi02", 22));
- ts.add(new Student("lisi007", 20));
- ts.add(new Student("lisi09", 19));
- ts.add(new Student("lisi09", 18));
-
- Iteratorit =ts.iterator();
- while(it.hasNext()){
- sop(it.next());
- }
- }
- }
复制代码 输出结果为:
作者: 杨庆雷 时间: 2014-4-16 11:44
补充一下:
当我们要往hashSet存东西的时候 需要 重写 equals()方法和hashCode()方法
当我们要往treeSet存东西的时候 如果实现comparable接口,需要 重写 compore()方法
如果不确定是往哪存 那么最好 三个方法都重写了
作者: 曹冬明 时间: 2014-4-16 12:02
简单的说就是Comparable是TreeSet中具体存储的对象去实现的一个借口,让对象本身具有可比性。Comparator是为TreeSet定义一种内部存放对象的比较方式。再简单点就是,一个我自己比,一个你帮我比
作者: 刘岳林 时间: 2014-4-16 12:04
自然顺序-----Comparable接口
复写Comparable接口中的compareTo方法。比较器在TreeSet中使用时,是通过创建TreeSet集合时,构造传递的。
比较器-------Comparator接口
就是实现了Comparator接口的类,这个类复写方法compare方法,它的返回值是int类型
1.返回0 代表相等,也就是重复,这时不能添加到集合中.
2.返回 正数 代表大于
3.返回 负数 代表小于.
如果元素有自然顺序,我们不想按照自然顺序排序,这时可以指定比较器.如果元素没有自然顺序,我们也可以指定其比较器,让其按照比较器进行排序
作者: 邵景伦 时间: 2014-4-17 09:22
谢谢你们
作者: luis 时间: 2014-4-17 13:16
排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。也种方式也成为元素的自然顺序,或者叫做默认顺序。
第二种排序方式。当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。
因为此,在定义一个类的时候,如果这个类要进行存储的话,一般要覆盖hashCode、equals方法,并实例Comparator接口。因为存到数据结构为哈希表的集合里要覆盖hashCode、equals方法,而存到数据结构为二叉树的,则需要实现Comparable接口,而且实现了该接口,还可以用Collections和Arrays的sort方法进行排序。最好也让这个类成为一个JavaBean,这让使用更方便。
注:当一个Student类具有可比较性(实现了Comparable接口),把它存到了TreeSet集合中,但是,它的自然排序不是我们想要的排序方式,这时就可以给TreeSet指定一个比较器(Comparator),则排序方式按比较器中的规则进行。
代码可以参考楼上的,代码很不错,
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |