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

Java基础——Set接口

2016-04-28 11:34 302 查看
  文章还按照上篇文章的UML图来分析:

  


Set和HashSet

  Set接口这一“派别”中,HashSet实现了Set接口,并且它还有一个子类LinkedHashSet。它们都根据对象的hashCode值来决定元素的存取位置,用equals方法来判断对象是否相等。所以重写对象equals方法时一定要根据实际场景重写hashCode方法。

  比如要判断是否是同一个人,判断他的身份证号是否相同就可以了,所以Person类可以用下面的方式重写equals方法和hashCode方法:

public class Person{
private String idCard;
private String name;

@Override
public boolean equals(Object o) {
if (((Person)o).idCard.equals(idCard)){
return true;
}
return false;
}
}


  虽然HashSet和LinkedHashSet都是根据对象的hashCode值来决定元素的存取位置,但是LinkedHashSet同时也使用链表来维护存入对象的次序,使对象看起来像是顺序插入的,所以当遍历LinkedHashSet时,将以对象插入的次序访问。两者的区别可以用下图来表示:

  


  由于这种特性,使得LinkedHashSet迭代访问Set中元素时效率较HashSet高,但是增删元素的效率较低。

TreeSet

  实现了SortedSet接口的TreeSet显著的特点就是排序,相同类型的元素进行排序才有意义,所以TreeSet中存放的元素必须是相同类型的,否则会报java.lang.ClassCastException异常。

  之前没有太关注但它的功能很实用,这里多说两句~

  TreeSet支持两种排序方式,自然排序和自定义排序。默认是自定义排序。但是TreeSet排序的前提是其中的元素要实现Comparable接口,或者有一个自定义的比较器。

  比较常用的String、Date、Integer、Float、BigDecimal等类都实现了Comparable接口( 实现了它唯一的compareTo(T o) 方法 ),所以TreeSet对这些对象的排序都是默认的,而且是默认升序排列的。

  自然排序示例:

  添加实现了Comparable接口的元素:

Set ts=new TreeSet();
ts.add("helloworld");
ts.add("apple");
ts.add("danny");
for (Iterator iterator = ts.iterator();
iterator.hasNext();) {
System.out.println(iterator.next());
}


  输出结果

apple
danny
helloworld


  如果TreeSet中需要添加自定义对象,则需要自定义一个比较器(实现Comparator接口)。

  添加拥有比较器的元素

public class TreeSetTest{
@Test
public void test(){
TreeSet ts=new TreeSet(new Person.PersonCompare());
Person p1=new Person("456","dannyhoo");
Person p2=new Person("123","dannySong");
ts.add(p1);
ts.add(p2);

for (Iterator iterator = ts.iterator(); iterator.hasNext();) {
System.out.println(((Person)iterator.next()).getName());
}
}
}

class Person{
private String idCard;
private String name;
public Person(String idCard,String name){
this.idCard=idCard; this.name=name;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

static class PersonCompare implements Comparator{
@Override
public int compare(Object o1, Object o2) {
Person p1=(Person)o1;
Person p2=(Person)o2;
return p1.idCard.compareTo(p2.idCard);//按照身份证号排序
}
}
}


  上面代码中的PersonCompare就是Person自己定义的比较器,需要实现Comparator接口并重写其compare接口,比较规则可以按照实际场景来定义。

【 转载请注明出处——胡玉洋《Java基础——Set接口》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息