黑马程序员:Java基础——Set集合之TreeSet
2014-10-26 17:42
831 查看
-------
Java EE培训、java培训、期待与您交流! ----------
与HashSet方法一致,示例如下:
需要注意的是,我已经将打印的两种方法封装起来,让这个类继承SystemOutPrintClass就会出现sop()以及sopln()方法。
输出结果为:
mjdk
njdi
nnnb
nnzi
我们可以看到,TreeSet并没有按照我们输入的先后顺序进行排序,而是通过ASCII码进行排序。
根据这个我们编出代码,可是运行结果却是让我们诧异:
我们看到出现了ClassCastException,为什么呢?因为,我们传入的是对象,对象和对象并没有可比性,JVN不知道该怎么比较于是就抛出了异常。
我们找到Comparable接口:
Comparable是这样解释的:
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
接口里面只有一个方法——compareTo()返回类型为int型。
那么我们只需要让我们的对象类实现Comparable就可以实现重写compareTo方法了。
我们依照年龄排序,当年龄相同时在依照姓名排序:
当我们再次运行的时候,发现所有项目已经存进来而且去除了重复项。以下是完整代码:
需要注意的是: 我的打印方法已经包装成了SystemOutPrintClass。以下是运行结果:
Name:lisi20,Age:20
Name:lisi001,Age:21
Name:lisi021,Age:21
Name:lisi02,Age:22
我们把左边的Student对象依次存入TreeSet集合中,同样按照年龄排序,那么存储时小数存到左面,大数存到右面,以二叉的形式来存储数据。当读取时,会像图中蓝色数字顺序读取。那么我们看到的就是已经排过序的元素。
为了保证元素唯一性的依据;compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。
TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在java.util包中有一个Comparator接口,这个接口强行对某个对象 collection 进行整体排序 的比较函数。
我们以上一节代码为基础,新建一个类,以下是全部代码:
运行结果如下:
Name:lisi001,Age:21
Name:lisi001,Age:22
Name:lisi02,Age:22
Name:lisi021,Age:21
Name:lisi20,Age:20
通过运行我们发现:
定义了比较器,将比较其对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主。我们可以这么理解,集合也调用过Comparable进行了排序,后来又被Comparator的排序覆盖掉了。
定义一个类,实现Comparator接口,覆盖compare方法。
分析:字符串本身具备比较性,但是它的比较方式不是所需要的。
使用Comparator会更方便
代码一:
代码二(匿名内部类);
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import com.micronote.list.collection.SystemOutPrintClass;
public class TreeSetTest3 extends SystemOutPrintClass {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int iNum = new Integer(s1.length()).compareTo(s2.length());
if (iNum == 0) {
return s1.compareTo(s2);
} else {
return iNum;
}
}
});
ts.add("abcd");
ts.add("cc");
ts.add("bcdef");
ts.add("bb");
ts.add("cde");
ts.add("defghi");
for (Iterator it = ts.iterator(); it.hasNext();) {
sopln(it.next());
}
}
}
运行结果为:
bb
cc
cde
abcd
bcdef
Java EE培训、java培训、期待与您交流! ----------
1.概念
TreeSet:可以对Set集合中的元素进行排序与HashSet方法一致,示例如下:
</pre><pre class="java" name="code">import java.util.Iterator; import java.util.TreeSet; import com.micronote.list.collection.SystemOutPrintClass; public class TreeSetDemo extends SystemOutPrintClass{ public static void main(String[] args) { TreeSet ts = new TreeSet(); ts.add("nnzi"); ts.add("mjdk"); ts.add("njdi"); ts.add("nnnb"); for(Iterator it = ts.iterator();it.hasNext();){ sopln(it.next()); } } }
需要注意的是,我已经将打印的两种方法封装起来,让这个类继承SystemOutPrintClass就会出现sop()以及sopln()方法。
输出结果为:
mjdk
njdi
nnnb
nnzi
我们可以看到,TreeSet并没有按照我们输入的先后顺序进行排序,而是通过ASCII码进行排序。
2.扩展练习
同样的我们给TreeSet集合中填入自定义集合。要求也与前面的ArrayList相同。根据这个我们编出代码,可是运行结果却是让我们诧异:
我们看到出现了ClassCastException,为什么呢?因为,我们传入的是对象,对象和对象并没有可比性,JVN不知道该怎么比较于是就抛出了异常。
我们找到Comparable接口:
Comparable是这样解释的:
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
接口里面只有一个方法——compareTo()返回类型为int型。
那么我们只需要让我们的对象类实现Comparable就可以实现重写compareTo方法了。
我们依照年龄排序,当年龄相同时在依照姓名排序:
@Override public int compareTo(Object o) { if(!(o instanceof Student)){ throw new RuntimeException("不是学生对象"); } Student s = (Student)o; if(this.iAge-s.iAge!=0){ return this.iAge-s.iAge; }else{ return this.sName.compareTo(s.sName); } }
当我们再次运行的时候,发现所有项目已经存进来而且去除了重复项。以下是完整代码:
import java.util.Iterator;
import java.util.TreeSet;
import com.micronote.list.collection.SystemOutPrintClass;
public class TreeSetTest extends SystemOutPrintClass{
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi001",21));
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi20",20));
ts.add(new Student("lisi021",21));
ts.add(new Student("lisi001",21));
for(Iterator it = ts.iterator();it.hasNext();){
Student stu = (Student)it.next();
sopln("Name:"+stu.getsName()+",Age:"+stu.getiAge());
}
}
}
class Student implements Comparable{
private String sName;
private int iAge;
Student(){}
Student(String sName,int iAge){
this.sName = sName;
this.iAge = iAge;
}
@Override public int compareTo(Object o) { if(!(o instanceof Student)){ throw new RuntimeException("不是学生对象"); } Student s = (Student)o; if(this.iAge-s.iAge!=0){ return this.iAge-s.iAge; }else{ return this.sName.compareTo(s.sName); } }
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public int getiAge() {
return iAge;
}
public void setiAge(int iAge) {
this.iAge = iAge;
}
}
需要注意的是: 我的打印方法已经包装成了SystemOutPrintClass。以下是运行结果:
Name:lisi20,Age:20
Name:lisi001,Age:21
Name:lisi021,Age:21
Name:lisi02,Age:22
3.TreeSet的数据结构
通过上一节的例子,我们来看一下TreeSet的数据结构。TreeSet的底层数据结构是二叉树,存取方式如图所示:我们把左边的Student对象依次存入TreeSet集合中,同样按照年龄排序,那么存储时小数存到左面,大数存到右面,以二叉的形式来存储数据。当读取时,会像图中蓝色数字顺序读取。那么我们看到的就是已经排过序的元素。
为了保证元素唯一性的依据;compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。
4.实现Comparator方式排序
刚才说了TreeSet排序的一种方式,还有一种方式:TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在java.util包中有一个Comparator接口,这个接口强行对某个对象 collection 进行整体排序 的比较函数。
我们以上一节代码为基础,新建一个类,以下是全部代码:
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import com.micronote.list.collection.SystemOutPrintClass; public class TreeSetDemo2 extends SystemOutPrintClass{ public static void main(String[] args) { TreeSet ts = new TreeSet(new MyCompare()); ts.add(new Student("lisi001",21)); ts.add(new Student("lisi02",22)); ts.add(new Student("lisi20",20)); ts.add(new Student("lisi021",21)); ts.add(new Student("lisi001",22)); for(Iterator it = ts.iterator();it.hasNext();){ Student stu = (Student)it.next(); sopln("Name:"+stu.getsName()+",Age:"+stu.getiAge()); } } } class MyCompare implements Comparator{ @Override public int compare(Object o1, Object o2) { Student s1 = (Student)o1; Student s2 = (Student)o2; int iNum = s1.getsName().compareTo(s2.getsName()); if(iNum!=0){ return iNum; }else{ return new Integer(s1.getiAge()).compareTo(new Integer((s2.getiAge()))); /*if(s1.getiAge()!=s2.getiAge()){ return s1.getiAge()-s2.getiAge(); }else{ return 0; }*/ } } }
运行结果如下:
Name:lisi001,Age:21
Name:lisi001,Age:22
Name:lisi02,Age:22
Name:lisi021,Age:21
Name:lisi20,Age:20
通过运行我们发现:
定义了比较器,将比较其对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主。我们可以这么理解,集合也调用过Comparable进行了排序,后来又被Comparator的排序覆盖掉了。
定义一个类,实现Comparator接口,覆盖compare方法。
5.TreeSet练习
练习:按照字符串长度排序。分析:字符串本身具备比较性,但是它的比较方式不是所需要的。
使用Comparator会更方便
代码一:
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import com.micronote.list.collection.SystemOutPrintClass; public class TreeSetTest2 extends SystemOutPrintClass{ public static void main(String[] args) { TreeSet ts = new TreeSet(new CompareStrLength()); ts.add("abcd"); ts.add("cc"); ts.add("bcdef"); ts.add("bb"); ts.add("cde"); ts.add("defghi"); for(Iterator it = ts.iterator();it.hasNext();){ sopln(it.next()); } } } class CompareStrLength implements Comparator{ @Override public int compare(Object o1, Object o2) { String s1 = (String)o1; String s2 = (String)o2; int iNum = new Integer(s1.length()).compareTo(s2.length()); if(iNum==0){ return s1.compareTo(s2); }else{ return iNum; } } }
代码二(匿名内部类);
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import com.micronote.list.collection.SystemOutPrintClass;
public class TreeSetTest3 extends SystemOutPrintClass {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int iNum = new Integer(s1.length()).compareTo(s2.length());
if (iNum == 0) {
return s1.compareTo(s2);
} else {
return iNum;
}
}
});
ts.add("abcd");
ts.add("cc");
ts.add("bcdef");
ts.add("bb");
ts.add("cde");
ts.add("defghi");
for (Iterator it = ts.iterator(); it.hasNext();) {
sopln(it.next());
}
}
}
运行结果为:
bb
cc
cde
abcd
bcdef
相关文章推荐
- 黑马程序员 java基础之TreeSet集合
- 黑马程序员java基础之集合Set中的TreeSet和泛型
- 黑马程序员————java基础--------集合之set接口的特点及应用
- 黑马程序员——Java基础—集合(Set、List)
- 黑马程序员——Java基础---集合(一)---Collection、set、list
- 黑马程序员_JavaSE基础17 之 集合框架 Vector LinkedList ArrayList HashSet LinkedHasSet TreeSet
- Java基础知识强化之集合框架笔记46:Set集合之TreeSet存储自定义对象并遍历练习2(自然排序)
- 黑马程序员——JAVA基础之set集合
- 黑马程序员——Java基础---集合(Set及Map)
- Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解
- 黑马程序员——Java基础---集合(Set接口及其子类、Map接口及其子类)
- 黑马程序员-JAVA基础-Java 集合之Set 接口
- Java基础视频教程第15天_集合之TreeSet、泛型
- 黑马程序员--Java基础学习笔记【集合-Set】
- 黑马程序员——java基础拾遗之集合框架(一) List 和 Set
- 黑马程序员 java基础之set集合
- 黑马程序员 java基础 集合框架之Set
- 黑马程序员—————Java基础----集合(二)set、map等
- Java基础知识强化之集合框架笔记43:Set集合之TreeSet存储Integer类型的元素并遍历
- 黑马程序员_java基础_集合(Collection和List、Set)