java中的类集之Set

         java容器中有三个接口:Iterator、collection、map这三个接口是java所有容器类的最大父接口。

         collection的子接口主要有list、set、queue;

                list的实现类主要有:ArrayList、LinkedList、Vector、Stack

                set的实现类主要有:HashSet、TreeSet、LinkedHashSet

                queue的主要实现类有:PriorityQueue

          Map接口的主要实现类有:HashMap、HashTable、TreeMap

 

1.Iterator接口的用法:

         Iterator接口主要用来遍历Collection集合中的元素,Iterator对象也被称为迭代器。Iterator接口隐藏了各种Collecton实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。当使用Iterator仅仅用于collection集合的输出,它没有盛装对象的能力,因此不能利用它来操作collection对象。

输出集合元素的代码(Iterator、foreache两种方式):

package com.shine.container;
import java.util.*;
public class IteratorDemo_01 {
    public static void main(String[] args){
        Collection books = new HashSet();
        books.add("语文");
        books.add("数学");
        books.add("英语");
        //用Iterator输出集合
        Iterator it = books.iterator();
        while(it.hasNext()){
            String book = (String)it.next();
            if(book.equals("语文")){
                it.remove();     //a
                //books.remove(book);//把a语句换成该语句会报错
            }
            book="测试字符串";
        }
        System.out.println(books);
       //使用foreach输出集合
        for(Object obj : books){
            String book = (String)obj;
            System.out.println(book);
            if(book.equals("数学"))
                books.remove(book);
        }
        System.out.println(books);
    }
}
2.Set和HashSet

       Set:Set集合中不允许有重复元素。set集合判断重复元素是根据equals()方法来判断的,只要equals方法 

              的返回值是false都能够成功的添加到set集合中,如果结果返回的是true则会抛出异常且添加失败。

       HashSet:HashSet中的元素不能保证其排列顺序,顺序有可能发生变化。HashSet不是同步的,如果多个

               线程同时访问一个HashSet则必须通过代码来保证其同步。HashSet判断两个元素是否相等是通过

               equals方法返回ture并且两个对象的hashCode()方法的返回值也相同。

   测试代码:

   package com.shine.container;

import java.util.HashSet;

//person类的equals方法的返回值为true,没有重写hashCode方法
class Person{
    public boolean equals(Object obj){
        return true;
    }
}
//person2类的hashCode方法的返回值为1,没有重写equals方法
class Person2{
    public int hashCode(){
        return 1;
    }
}
//类person3的hashCode方法的返回值为2,并且重写了equals方法
class Person3{
    public boolean equals(Object obj){
        return true;
    }
    public int hashCode(){
        return 2;
    }
}
public class HashSetDemo_01 {
    public static void main(String[] args) {
        HashSet persons = new HashSet();
        persons.add(new Person());
        persons.add(new Person());
       
        persons.add(new Person2());
        persons.add(new Person2());
       
        persons.add(new Person3());
        persons.add(new Person3());
       
        System.out.println(persons);

    }
}
    运行结果:[com.shine.container.Person2@1, com.shine.container.Person2@1,   

                      com.shine.container.Person3@2, com.shine.container.Person@22adc446,

                     com.shine.container.Person@3e30e173]

    只有person3的第二个对象没有添加进去。

    所以,当我们把一个对象放到HashSet中时,应该重写这个对象实现类的equals和hashCode方法。

    hashCode()方法的重要性:当程序向HashSet集合中添加元素时,HashSet会根据该元素的hashCode()值

    来计算它的存储位置。也就是说,每个元素的hashCode()值可以决定它的存储索引。HashSet采用元素的

    hashCode()值来计算其索引,从而可以自由增加HashSet的长度,并可以根据元素的hashCode()值来访问

    元素。这也是HashSet速度快的原因。

 

LinkedHashSet:

           LinkedHashSet是HashSet的一个子类,它也是根据元素的HashSet值来决定元素的存储位置的,它同

     时使用链表来维护元素的顺序。

           LinkedHashSet记录了元素的添加顺序,它依然不允许内部有重复元素。

TreeSet

          TreeSet是sortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

          TreeSet采用红黑树的数据结构来存储 集合元素。TreeSet支持两种 排序方法:自然排序和定制排序。

     1.自然排序:

               TreeSet会调用集合元素的compareTo(0bject obj)方法来比较元素之间的大小关系,然后将集合元

          素按升序排列,这种方式就是自然排序。

               java中有一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一

           个整数值,实现该接口的类必须实现该方法,实现了该接口的对象就可以比价大小。java中的一些常

            用类已经实现了Comparable接口,并且提供了比较大小的标准。下面是这些常用类:

                  BigDecimal、BigInteger以及所有的数值型对应的包装类:按他们对应的数值大小进行比较。

                  Character:按字符的UNICODE值进行比较。

                  Boolean:true对应的包装类实例大于false对应的包装类实例。

                  String:按字符串中的UNICODE值进行比较。

                  Date、Time:后面的时间、日期比前面的时间、日期大。

             如果试图把一个对象添加到TreeSet中,则该对象必须实现Comparable接口,否则程序将会抛出异

             常。

      2.定制排序:

              TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列。如果需要实现定制排序,

           则需要Comparator接口的帮助。该接口里有一个int compare(T o1,T o2)方法。

              如果需要定制排序,则需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合

           关联,由该Comaprator对象负责集合元素的排序逻辑。

       

 

            当通过Comparator对象来实现TreeSet的定制排序时,依然不可以向TreeSet中添加类型不同的对

       象,否则会引发ClassCastException异常。使用定制排序时,TreeSet对集合元素排序不管集合元素本身

       的大小,而是由Comparator对象负责集合元素的排序规则。TreeSet判断两个元素相等的标准是:通过

       Comparator比较两个元素返回了0,这样TreeSet不会把第二个元素添加到集合中。

 

总结:

       HashSet的性能总是比TreeSet好,因为TreeSet需要额外的红黑树来维护集合元素的次序。只有当需要一个排序的Set时才使用TreeSet。

       对于HashSet的子类LinkedHashSet普通的插入删除操作,LinkedHashSet的速度比HashSet慢,这是由于维护链表的额外开销造成的。不过,因为有了链表,遍历LinkedHashSet会更快。

       EnumSet是所有Set实现类中最好的,但它只能保存同一个枚举类的枚举值作为集合元素。

       Set的三个实现类HashSet、TreeSet和EnumSet都不是线程安全的。通常可以通过Collections工具类的synchronizedSortedSet方法“包装"该Set集合。此操作最好在创建时进行,以防止对Set集合的意外非同步访问。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值