java核心数据结构(三)——Set类族



一、Set核心实现类

如上图,Set和List是Collection接口的两个分支,比较重要且频繁使用的有HashSet、LinkedHashSet和TreeSet。比较鲜明的特点就是整个Set以及它的实现类中,集合中的元素是不能重复的,还有一个比较有意思的点在于,Set中的主要实现类都是对Map实现类的封装,例如HashSet封装了HashMap,LinkedHashSet封装了LinkedHashMap,TreeSet封装了TreeMap。查看源码,不难发现,HashSet中提供的构造方法,实际初始化的是一个HashMap对象。其他两个实现类亦是如此。

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
   public HashSet() {
        map = new HashMap<>();
    }  
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }  
} 
//TreeSet构造方法
    public TreeSet() {
        this(new TreeMap<E,Object>());
    } 
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }  

而且不难发现,HashSet中的数据操作方法都是通过内部维护的一个HashMap对象,并将与Set相关的实现委托给改map对象进行处理。

 private transient HashMap<E,Object> map;
  public int size() {
        return map.size();
    } 
   public boolean isEmpty() {
        return map.isEmpty();
    }

      所以对于与Map各实现类的特点Set相应的实现类也具备。这里进行简单总结:

Set

对应Map

特点

HashSet

HashSet

基于hash的快速插入,元素间无序

LinkedHashSet

LinkedHashMap

同上,元素有序,遍历集合时按照FIFO

TreeSet

TreeMap

高效的基于Key的排序算法

 二、优化集合操作

1、分离循环调用的代码

例如:

		//优化前
		for(int i=0;i<list.size();i++)
		{
		}		
		//优化后
		int count=list.size();
		for(int i=0;i<count;i++)
		{}
优化后,size方法只被调用一次,而不是每次都循环执行。同样循环体中的方法也注意这样的优化,集合中元素越多,这样的处理就越有意义。

 2、省略相同操作

		//简化前
		if(list.get(i).indexOf("max")!=-1 && list.get(i).indexOf("zhong")!=-1
				||list.get(i).indexOf("ai")!=-1)
		{}
		//简化为
		String s=null;
		if(s=list.get(i).indexOf("max")!=-1 && s.indexOf("zhong")!=-1
				||s.indexOf("ai")!=-1)
		{}
3、必要时还可直接调用原生的参数。如Vector类中的elementCount参数来替代对象的size方法以减少方法调用。这种优化程度应该是对系统精度要求极高。但也不失为一种思路。

你可能感兴趣的:(java核心数据结构(三)——Set类族)