JAVA自学教程之(常用对象API)— Set集合:TreeSet集合、比较器。
一、LinkedHashSet集合
HashSet下有子类LinkedHashSet
API文档关于LinkedHashSet的解释:
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。(如果在s.contains(e) 返回true 后立即调用 s.add(e),则元素 e 会被重新插入到 sets 中。)
此实现可以让客户免遭未指定的、由 HashSet
提供的通常杂乱无章的排序工作,而又不致引起与TreeSet
关联的成本增加
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.LinkedHashSet;
- public class Main
- {
- public static void main(String[] args)
- {
- //HashSet hash = new HashSet();无序
- HashSet hash = new LinkedHashSet();
- hash.add(“b”);
- hash.add(“a”);
- hash.add(“c”);
- hash.add(“d”);
- Iterator it = hash.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
如上,用LinkedHashSet就能够实现有序存储,但是有没有序不重要,关键是保证唯一。
二、TreeSet集合
API文档解释:
基于 TreeMap
的 NavigableSet
实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator
进行排序,具体取决于使用的构造方法。
此实现为基本操作(add
、remove
和contains
)提供受保证的 log(n) 时间开销。
注意,如果要正确实现 Set
接口,则 set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致。
总结一句话就是,TreeSet集合可以对Set集合中的元素进行排序,速度快,且不同步
而TreeSet的储存方式,实际上根据二叉树(红黑树)的存储特点进行存储,左孩子小于父亲,右孩子大于父亲
- import java.util.Iterator;
- import java.util.TreeSet;
- public class Main
- {
- public static void main(String[] args)
- {
- TreeSet tree = new TreeSet();
- tree.add(“ad”);
- tree.add(“abc”);
- tree.add(“dsa”);
- tree.add(“bcd”);
- Iterator it = tree.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
按照字典序排序输出结果。
TreeSet判断元素唯一的方式,就是根据比较方法的返回结果是否是0,是,则表示相同,不存储,与HashCode、equals无关。
- import java.util.Iterator;
- import java.util.TreeSet;
- public class Man /*extends Object*/ implements Comparable
- {
- private String name;
- private int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public Man() {
- super();
- // TODO Auto-generated constructor stub
- }
- public Man(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public int compareTo(Object arg0) {//对象的自然排序
- // TODO Auto-generated method stub
- if(!(arg0 instanceof Man))
- throw new ClassCastException();
- Man man = (Man)arg0;
- int te = this.age - man.age;//先按年龄排,再姓名
- return te==0?this.name.compareTo(man.name):te;
- }
- }
- public class Main {
- public static void main(String[] args)
- {
- TreeSet tree = new TreeSet();
- tree.add(new Man(“ad”,11));
- tree.add(new Man(“ac”,12));
- tree.add(new Man(“sf”,14));
- tree.add(new Man(“d”,11));
- tree.add(new Man(“ad”,11));
- tree.add(new Man(“ad”,12));
- Iterator it = tree.iterator();
- while(it.hasNext())
- {
- Man man = (Man)it.next();
- System.out.println(man.getName()+”::”+man.getAge());
- }
- }
- }
TreeSet对元素进行排序的方式一:
要让元素自身具备比较功能,就要实现Comparable接口,覆盖CompareTo方法
如果对象不具备自然排序,或具备自然排序但是其排序方式不是我们需要的
TreeSet对元素进行排序的方式二(开发常用):
让集合自身具备比较功能,构造一个比较器,复写compare方法,将该类对象作为参数传递给TreeSet的构造函数
比较器比较常用,因为它可以避免一些 对象自身不足
- import java.util.Iterator;
- import java.util.TreeSet;
- import java.util.Comparator;
- public class ComparatorRule implements Comparator {
- //构造一个根据Man类的name进行排序的比较器
- @Override
- public int compare(Object arg0, Object arg1) {
- // TODO Auto-generated method stub
- Man man = (Man)arg0;
- Man man2 = (Man)arg1;
- int te = man.getName().compareTo(man2.getName());
- //return 1;有序,输出,改变了二叉树的储存特点
- return te==0?man.getAge()-man2.getAge():te;
- }
- }
- public class Man /*extends Object*/ implements Comparable
- {
- private String name;
- private int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public Man() {
- super();
- // TODO Auto-generated constructor stub
- }
- public Man(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public int compareTo(Object arg0) {
- // TODO Auto-generated method stub
- if(!(arg0 instanceof Man))
- throw new ClassCastException();
- Man man = (Man)arg0;
- int te = this.age - man.age;
- return te==0?this.name.compareTo(man.name):te;
- }
- }
三、练习:比较器的应用
对字符串进行长度排序
- import java.util.Comparator;
- import java.util.Iterator;
- import java.util.TreeSet;
- class ComparatorLengh implements Comparator
- {
- public int compare(Object arg0, Object arg1) {
- // TODO Auto-generated method stub
- String str0 = (String) arg0;
- String str1 = (String) arg1;
- int te = str0.length() - str1.length();
- return te==0?str0.compareTo(str1):te;
- }
- }
- public class Main
- {
- public static void main(String[] args)
- {
- TreeSet tree = new TreeSet(new ComparatorLengh());
- tree.add(“ad”);
- tree.add(“abssc”);
- tree.add(“dsafsd”);
- tree.add(“bcd”);
- tree.add(“b”);
- Iterator it = tree.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
- http://blog.csdn.net/wjw0130/article/details/40301627