您的位置:首页 > 编程语言 > Java开发

JAVA学习第三十七课(常用对象API)— Set集合:TreeSet集合、比较器

2014-10-20 15:51 671 查看
一、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());
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: