Collection接口表示一组对象,这些对象也成为Collection的元素。一些Collection接口允许有重复元素,而另一些则不允许。一些Collection接口是有序的,而另一些则是无序的。
重复:两个对象通过equals判断相等。(equals子类对象可以复写)
有序:元素存入的顺序和取出的顺序相同。
set接口存放的元素是无序的且不包含重复元素。List接口存放的元素是有序的并且是允许重复的。
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 实现Set接口的容器存储对象时,根据每个对象的哈希码值(调用hashCode方法获得)用固定的算法算出它的存储索引,
* 把对象存放在一个叫散列表的相应位置中;如果该位置没有其他元素,就只需直接存入。如果该位置已经有其他元素,
* 就会将新元素与该位置的【所有】对象进行比较(调用equals),以查看该容器中是否已经存入该对象,如果不存在该对象,
* 就存放该对象,若已经存在则直接使用该【存在】的对象。
* @author wanghl
*
* 【Set元素不能重复】
* 【List元素可重复】
*
*【hasCode散列介绍:】
*如果一个容器有100个元素,在进行添加一个元素时,由于需要判断是否重复,那么需要进行100次equals方法。如果每增加一个元素,
*就需要多执行一次equals,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了,这样效率就大大降低。于是,java
*采用了哈希表的原理。哈希算法也成为散列算法,是将数据依据特定的算法直接指定到一个地址上(我们暂且将hasCode值当做对象存储的物理
*地址的一个索引,暂时不要关心算法计算)。那么,添加新元素时,先通过hasCode索引查看这个位置是否已经存入对象,如果不存在,则直接将
*新元素存放在这个位置,不需要再调用equals方法。如果已经存在对象,则在调用equals方法进行比较,相同就不存,直接使用存在元素,不同的话
*就散列其他地址。这样就使equals方法调用的次数大大降低。
*【两个对象相同,那么他们的hasCode一定相同,hasCode相同,两个对象不一定相同】
*【存入到Set集合的对象,不一定会调用equals方法】
*/
public class SetTest {
public static void main(String args[]){
/**
* HashSet是Set接口实现类之一,使用哈希码值进行存放,所以也能够快速查找。
* 【HashSet不保存加入容器的元素的顺序】
*/
HashSet
set1 = new HashSet
(); System.out.println("------------------------hasCode与equals对Set接口实现类的影响"); /** * 打印结果为: * p--->12Persion1@01 * p--->12Persion1@02 * Set count is:1 * Persion1 对象为:12Persion1@01 * 【验证:】set接口,如果两个元素的hasCode相等,equals相等,则说明对象存在,直接使用该存在对象,不进行【覆盖】。 */ Persion1 pa1 = new Persion1(12); Persion1 pa2 = new Persion1(12); System.out.println("p--->"+pa1); System.out.println("p--->"+pa2); set1.add(pa1); set1.add(pa2); System.out.println("Set count is:"+set1.size()); for(Persion1 p :set1){ System.out.println("Persion1 对象为:"+p); } System.out.println("---------------------------------------"); //------------------------------------------- /** * 【注意:】Persion1与Persion2,仅仅在equals方法判断的地方存在差异。 * 【打印:】 * p--->12Persion2@01 * p--->12Persion2@02 * Set count is:2 * Persion2 对象为:12Persion2@02 * Persion2 对象为:12Persion2@01 * 【说明:】 * 下面的 这两个对象存放在同一个hasCode所算出的索引上,由于equals不同,故而可存。 */ HashSet
set2 = new HashSet
(); Persion2 pb1 = new Persion2(12); Persion2 pb2 = new Persion2(12); System.out.println("p--->"+pb1); System.out.println("p--->"+pb2); set2.add(pb1); set2.add(pb2); System.out.println("Set count is:"+set2.size()); for(Persion2 p :set2){ System.out.println("Persion2 对象为:"+p); } System.out.println("---------------------------------------"); //------------------------------------------- /** * 输出是无须的。 * 【打印:】 * p ---->44Persion1@06 * p ---->33Persion1@05 * p ---->22Persion1@04 * p ---->11Persion1@03 * p ---->better * p ---->best * p ---->good */ HashSet set3 = new HashSet(); Persion1 pc1 = new Persion1(11); Persion1 pc2 = new Persion1(22); Persion1 pc3 = new Persion1(33); Persion1 pc4 = new Persion1(44); set3.add(pc1); set3.add(pc2); set3.add(pc3); set3.add(pc4); set3.add("good"); set3.add("better"); set3.add("best"); Iter