java中的Set集合

1.Set集合类似于一个罐子,集合中的多个对象之间没有明显的顺序,其方法几乎和Collection基本上完全一样,但集合中不允许包含重复的元素。


2.Set集合判断两个元素是否相同的方法是使用equals方法,而非==。


3.HashSet类

HashSet是按照Hash算法来存储集合中的元素,其特点:

1)是不能保证元素的排列顺序

2)Hash不是同步的,如果多个线程同时访问一个HashSet,则必须通过代码来保证其同步。

3)集合中的元素值可以是null。

4)判断过程:

     当向HashSet中添加一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode值,然后根据该值决定该对象的存储位置,但是如果有两个元素通过equals()方法比较返回true,而它们的hashCode()方法返回值不等,HashSet也会将它们存储在不同的位置。

5)重写方法:

    一般在重写hashCOde()时,也要对应的重写equals()方法,且当equals()方法返回true时,这两个对象的hashCode()方法应返回相同的值。


4.LinkedHashSet类

   该类为HashSet的子类,也是根据元素的hashCode()值来决定其存储位置,但是通过链表来维护元素的次序(存储)。


5.TreeSet类

  该类为SortedSet接口的实现类,其采用红黑树的数据结构来存储集合中的元素,即其中的元素时有序的。

 1)自然排序+定制排序

  前提:试图把一个对象添加到TreeSet时,该对象的类必须实现Comparable接口(comparTo(Object obj)方法),否则程序将抛出异常。

              并通过compareTo(Object obj)方法与容器中的其它对象比较大小,如果比较返回0,则二者相等,否则,不等。

 注意:当重写对象对应类的equals和compareTo()方法时,应保证二者一致。即前者返回true时,后者返回0.

             且当添加一个可变对象后,并且修改了可变对象的Field,有可能导致它与其它对象的大小顺序发生了变化,但TreeSet不会调整他们的顺序,甚至有可能出现                                  compareTo()的返回结果为0。一般向这两个集合中放入不可变对象。

  定制排序举例:

import java.util.*;
class M
{
	int age;
	public M(int age)
	{
		this.age=age;
	}
	public String toString()
	{
		return "M对象(age:"+age+")";
	}
}
class TestTreeSet3 
{
	public static void main(String[] args) 
	{
		TreeSet ts=new TreeSet(new Comparator()
		{
			public int compare(Object o1,Object o2)
			{
				M m1=(M)o1;
				M m2=(M)o2;
				return m1.age<m2.age?-1:m1.age>m2.age?1:0;//从小到大排序
			}
		});
		ts.add(new M(5));
		ts.add(new M(9));
		System.out.println(ts);
	}
}

6.EnumSet类

    该类是一个专门为枚举类设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显示或隐式指定,且 不允许加入null元素。

    举例如下:

import java.util.*;
enum Season
{
    SPRING,SUMMER,FALL,WINTER
}
class EnumSetTest 
{
	public static void main(String[] args) 
	{
		//创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
		EnumSet es1=EnumSet.allOf(Season.class);
		System.out.println(es1);
        //创建一个EnumSet空集合,制定其集合类型为Season类的枚举值
		EnumSet es2=EnumSet.noneOf(Season.class);
        System.out.println(es2);
		es2.add(Season.WINTER);
		es2.add(Season.SPRING);
		System.out.println(es2);
		//指定枚举值创建EnumSet集合
		EnumSet es3=EnumSet.of(Season.SUMMER,Season.WINTER);
		System.out.println(es3);
		EnumSet es4=EnumSet.range(Season.SUMMER,Season.WINTER);
		System.out.println(es4);
        //es5+es4=全部的枚举值
		EnumSet es5=EnumSet.complementOf(es4);
		System.out.println(es5);
		//使用集合来创建EnumSet集合,要求集合中的元素为同类型的枚举值
		Collection c=new HashSet();
		c.clear();
		c.add(Season.FALL);
		c.add(Season.SPRING);
		EnumSet ens=EnumSet.copyOf(c);
		System.out.println(ens);
	}
}


7.各Set实现类的性能分析

    只有当需要一个保持排序的Set时,使用TreeSet,否则使用HashSet.

   而对于普通的插入和删除操作LinkedHashSet比HashSet要慢一点,但是遍历LinkedHashSet会更快。

  EnumSet是所有Set实现类中性能最好的,但它只能保存同一枚举类型的枚举值。

   但这三者都是线程不安全的,有多线程时修改Set集合时,则必须手动保证Set集合的同步性。一般使用Collection的synchronizedSortedSet方法来包装Set集合。

  如:SortedSet s=Collection.synchronizedSortedSet(new TreeSet(...))。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值