每日记载内容总结44

HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放;
LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代;
TreeSet:提供一个使用树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。

HashSet:

(来源:深入Java集合学习系列:HashSet的实现原理)
不保证set的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成。
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

  1. iterator()方法返回对此 set 中元素进行迭代的迭代器。返回元素的顺序并不是特定的。底层调用HashMap的keySet返回所有的key,这点反应了HashSet中的所有元素都是保存在HashMap的key中,value则是使用的PRESENT对象,该对象为static final。

     public Iterator<E> iterator() {  
         return map.keySet().iterator();  
     }
    
  2. size()返回此 set 中的元素的数量(set 的容量)。底层调用HashMap的size方法,返回HashMap容器的大小。

     public int size() {  
         return map.size();  
     }
    
  3. isEmpty(),判断HashSet()集合是否为空,为空返回 true,否则返回false。

     public boolean isEmpty() {  
         return map.isEmpty();  
     }		
    
  4. contains(),判断某个元素是否存在于HashSet()中,存在返回true,否则返回false。更加确切的讲应该是要满足这种关系才能返回true:(onull ? enull : o.equals(e))。底层调用containsKey判断HashMap的key值是否为空。

     public boolean contains(Object o) {  
         return map.containsKey(o);  
     }
    
  5. add()如果此 set 中尚未包含指定元素,则添加指定元素。如果此Set没有包含满足(enull ? e2null : e.equals(e2)) 的e2时,则将e2添加到Set中,否则不添加且返回false。由于底层使用HashMap的put方法将key = e,value=PRESENT构建成key-value键值对,当此e存在于HashMap的key中,则value将会覆盖原有value,但是key保持不变,所以如果将一个已经存在的e元素添加中HashSet中,新添加的元素是不会保存到HashMap中,所以这就满足了HashSet中元素不会重复的特性。

     public boolean add(E e) {  
         return map.put(e, PRESENT)==null;  
     }
    
  6. remove如果指定元素存在于此 set 中,则将其移除。底层使用HashMap的remove方法删除指定的Entry。

     public boolean remove(Object o) {  
         return map.remove(o)==PRESENT;  
     }  
    
  7. clear从此 set 中移除所有元素。底层调用HashMap的clear方法清除所有的Entry。

     public void clear() {  
         map.clear();  
     }  
    
  8. clone返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。

     public Object clone() {  
         try {  
             HashSet<E> newSet = (HashSet<E>) super.clone();  
             newSet.map = (HashMap<E, Object>) map.clone();  
             return newSet;  
         } catch (CloneNotSupportedException e) {  
             throw new InternalError();  
         }  
     }
    

特点:

  • 不能保证元素的排列顺序,顺序有可能发生变化
  • 不是同步的
  • 集合元素可以是null,但只能放入一个null

LinkedHashSet

LinkedHashSet是具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
注意,此实现不是同步的。如果多个线程同时访问链接的哈希Set,而其中至少一个线程修改了该Set,则它必须保持外部同步。

对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。
LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同,因此LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个LinkedHashMap来实现,在相关操作上与父类HashSet的操作相同,直接调用父类HashSet的方法即可。

LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

TreeSet

TreeSet存储对象的时候, 可以排序, 但是需要指定排序的算法
Integer能排序(有默认顺序), String能排序(有默认顺序), 自定义的类存储的时候出现异常(没有顺序)
如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口
在类上implement Comparable
重写compareTo()方法
在方法内定义比较算法, 根据大小关系, 返回正数负数或零
在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储

public class TestIndexEntity implements Comparable{
	private Integer id;
	private String name;
	private String desp;
	private String content;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDesp() {
		return desp;
	}

	public void setDesp(String desp) {
		this.desp = desp;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Override
	public int compareTo(Object o) {
		TestIndexEntity entity = (TestIndexEntity)o;
		int result = id < entity.id ? -1 : (id == entity.id ? 0 : 1);
		return result;
	}
	

}
原文地址:https://www.cnblogs.com/cuiyf/p/6212126.html