JAVA自学教程之(常用对象API)— Set集合:TreeSet集合、比较器



JAVA自学教程之(常用对象API)— Set集合:TreeSet集合、比较器。

一、LinkedHashSet集合

HashSet下有子类LinkedHashSet

API文档关于LinkedHashSet的解释:

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序 受在 set 中重新插入的 元素的影响。(如果在s.contains(e) 返回true 后立即调用 s.add(e),则元素 e 会被重新插入到 sets 中。)

此实现可以让客户免遭未指定的、由 HashSet 提供的通常杂乱无章的排序工作,而又不致引起与TreeSet 关联的成本增加

 

  1. import java.util.HashSet;
  2. import java.util.Iterator;
  3. import java.util.LinkedHashSet;
  4. public class Main
  5. {
  6.     public static void main(String[] args)
  7.     {
  8.         //HashSet hash = new HashSet();无序
  9.         HashSet hash = new LinkedHashSet();
  10.         hash.add(“b”);
  11.         hash.add(“a”);
  12.         hash.add(“c”);
  13.         hash.add(“d”);
  14.         Iterator it = hash.iterator();
  15.         while(it.hasNext()){
  16.             System.out.println(it.next());
  17.         }
  18.     }
  19. }

如上,用LinkedHashSet就能够实现有序存储,但是有没有序不重要,关键是保证唯一。

 

 

二、TreeSet集合

 

API文档解释:

基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator 进行排序,具体取决于使用的构造方法。

此实现为基本操作(addremove 和contains)提供受保证的 log(n) 时间开销。

注意,如果要正确实现 Set 接口,则 set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致

总结一句话就是,TreeSet集合可以对Set集合中的元素进行排序,速度快,且不同步

而TreeSet的储存方式,实际上根据二叉树(红黑树)的存储特点进行存储,左孩子小于父亲,右孩子大于父亲

 

  1. import java.util.Iterator;
  2. import java.util.TreeSet;
  3. public class Main
  4. {
  5.     public static void main(String[] args)
  6.     {
  7.         TreeSet tree = new TreeSet();
  8.         tree.add(“ad”);
  9.         tree.add(“abc”);
  10.         tree.add(“dsa”);
  11.         tree.add(“bcd”);
  12.         Iterator it = tree.iterator();
  13.         while(it.hasNext()){
  14.             System.out.println(it.next());
  15.         }
  16.     }
  17. }


按照字典序排序输出结果。

 

 

TreeSet判断元素唯一的方式,就是根据比较方法的返回结果是否是0,是,则表示相同,不存储,与HashCode、equals无关。

 

  1. import java.util.Iterator;
  2. import java.util.TreeSet;
  3. public class Man /*extends Object*/ implements Comparable
  4. {
  5.     private String name;
  6.     private int age;
  7.     public String getName() {
  8.         return name;
  9.     }
  10.     public void setName(String name) {
  11.         this.name = name;
  12.     }
  13.     public int getAge() {
  14.         return age;
  15.     }
  16.     public void setAge(int age) {
  17.         this.age = age;
  18.     }
  19.     public Man() {
  20.         super();
  21.         // TODO Auto-generated constructor stub
  22.     }
  23.     public Man(String name, int age) {
  24.         super();
  25.         this.name = name;
  26.         this.age = age;
  27.     }
  28.     @Override
  29.     public int compareTo(Object arg0) {//对象的自然排序
  30.         // TODO Auto-generated method stub
  31.         if(!(arg0 instanceof Man))
  32.             throw new ClassCastException();
  33.             Man man = (Man)arg0;
  34.         int te = this.age - man.age;//先按年龄排,再姓名
  35.         return te==0?this.name.compareTo(man.name):te;
  36.     }
  37. }
  38. public class Main {
  39.     public static void main(String[] args)
  40.     {
  41.         TreeSet tree = new TreeSet();
  42.         tree.add(new Man(“ad”,11));
  43.         tree.add(new Man(“ac”,12));
  44.         tree.add(new Man(“sf”,14));
  45.         tree.add(new Man(“d”,11));
  46.         tree.add(new Man(“ad”,11));
  47.         tree.add(new Man(“ad”,12));
  48.         Iterator it = tree.iterator();
  49.         while(it.hasNext())
  50.         {
  51.             Man man = (Man)it.next();
  52.             System.out.println(man.getName()+”::”+man.getAge());
  53.         }
  54.     }
  55. }

TreeSet对元素进行排序的方式一:

 

要让元素自身具备比较功能,就要实现Comparable接口,覆盖CompareTo方法

 

如果对象不具备自然排序,或具备自然排序但是其排序方式不是我们需要的

TreeSet对元素进行排序的方式二(开发常用):

让集合自身具备比较功能,构造一个比较器,复写compare方法,将该类对象作为参数传递给TreeSet的构造函数

比较器比较常用,因为它可以避免一些 对象自身不足

 

  1. import java.util.Iterator;
  2. import java.util.TreeSet;
  3. import java.util.Comparator;
  4. public class ComparatorRule implements Comparator {
  5. //构造一个根据Man类的name进行排序的比较器
  6.     @Override
  7.     public int compare(Object arg0, Object arg1) {
  8.         // TODO Auto-generated method stub
  9.         Man man = (Man)arg0;
  10.         Man man2 = (Man)arg1;
  11.         int te = man.getName().compareTo(man2.getName());
  12.         //return 1;有序,输出,改变了二叉树的储存特点
  13.         return te==0?man.getAge()-man2.getAge():te;
  14.     }
  15. }
  16. public class Man /*extends Object*/ implements Comparable
  17. {
  18.     private String name;
  19.     private int age;
  20.     public String getName() {
  21.         return name;
  22.     }
  23.     public void setName(String name) {
  24.         this.name = name;
  25.     }
  26.     public int getAge() {
  27.         return age;
  28.     }
  29.     public void setAge(int age) {
  30.         this.age = age;
  31.     }
  32.     public Man() {
  33.         super();
  34.         // TODO Auto-generated constructor stub
  35.     }
  36.     public Man(String name, int age) {
  37.         super();
  38.         this.name = name;
  39.         this.age = age;
  40.     }
  41.     @Override
  42.     public int compareTo(Object arg0) {
  43.         // TODO Auto-generated method stub
  44.         if(!(arg0 instanceof Man))
  45.             throw new ClassCastException();
  46.             Man man = (Man)arg0;
  47.         int te = this.age - man.age;
  48.         return te==0?this.name.compareTo(man.name):te;
  49.     }
  50. }

三、练习:比较器的应用

 

对字符串进行长度排序

 

 

  1. import java.util.Comparator;
  2. import java.util.Iterator;
  3. import java.util.TreeSet;
  4. class ComparatorLengh implements Comparator
  5. {
  6.     public int compare(Object arg0, Object arg1) {
  7.         // TODO Auto-generated method stub
  8.         String str0 = (String) arg0;
  9.         String str1 = (String) arg1;
  10.         int te = str0.length() - str1.length();
  11.         return te==0?str0.compareTo(str1):te;
  12.     }
  13. }
  14. public class Main
  15. {
  16.     public static void main(String[] args)
  17.     {
  18.         TreeSet tree = new TreeSet(new ComparatorLengh());
  19.         tree.add(“ad”);
  20.         tree.add(“abssc”);
  21.         tree.add(“dsafsd”);
  22.         tree.add(“bcd”);
  23.         tree.add(“b”);
  24.         Iterator it = tree.iterator();
  25.         while(it.hasNext()){
  26.             System.out.println(it.next());
  27.         }
  28.     }
  29. }
  30. http://blog.csdn.net/wjw0130/article/details/40301627