JAVA学习第三十七课(常用对象API)- 集合框架(五)— Set集合:TreeSet集合
一、LinkedHashSet集合
HashSet下有子类LinkedHashSet
API文档关于LinkedHashSet的解释:
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)
此实现可以让客户免遭未指定的、由 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()); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。