转载请注明出处:http://blog.csdn.net/droyon/article/details/22781533
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<Persion1> set1 = new HashSet<Persion1>();
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<Persion2> set2 = new HashSet<Persion2>();
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");
Iterator<Persion1> iterator = set3.iterator();
while(iterator.hasNext()){
Object p = iterator.next();
System.out.println("p ---->"+p+",hasCode is:"+p.hashCode());
}
System.out.println("*********************************************");
//-------------------------------------------
/**
* LinkedHashSet 根据哈希码进行存放,同时用链表记录元素的加入顺序。
* 通过链表存储对象,一般插入和删除效率较高,检索效率较低。
*/
LinkedHashSet linkedSet = new LinkedHashSet();
/**
* LinkedHashSet记录元素加入顺序
* 打印:
* p ***> is:55Persion1@07,hasCode is:0
* p ***> is:66Persion1@08,hasCode is:0
* p ***> is:77Persion1@09,hasCode is:0
* p ***> is:88Persion1@010,hasCode is:0
* p ***> is:aaaa,hasCode is:2986048
* p ***> is:bbbb,hasCode is:3016832
* p ***> is:cccc,hasCode is:3047616
*/
Persion1 pd1 = new Persion1(55);
Persion1 pd2 = new Persion1(66);
Persion1 pd3 = new Persion1(77);
Persion1 pd4 = new Persion1(88);
linkedSet.add(pd1);
linkedSet.add(pd2);
linkedSet.add(pd3);
linkedSet.add(pd4);
linkedSet.add("aaaa");
linkedSet.add("bbbb");
linkedSet.add("cccc");
for(Object p:linkedSet){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
//-------------------------------------------
/**
* 有多个不同类型的对象加入TreeSet,就会报异常。
* 对于自定义的类,它的对象只能存放一个,而且实现类不需要实现【Comparable接口】。
* 但是,如果 想要存放多个自定义的类的对象,
* 不实现Comparable接口就会发生java.lang.ClassCastException异常 。
*/
Set treeSet = new TreeSet();
Persion1 pe1 = new Persion1(12);
treeSet.add(pe1);
/*treeSet.add(new String("hello"));*/
Iterator itor = treeSet.iterator();
while(itor.hasNext()){
System.out.println("TreeSet p is:"+itor.next());
}
System.out.println("---------------------------------------");
//-------------------------------------------
/**
* Set排序
* Persion3实现了排序的接口Comparable
* p ***> is:0Persion3@07,hasCode is:0
* p ***> is:1Persion3@01,hasCode is:0
* p ***> is:2Persion3@03,hasCode is:0
* p ***> is:4Persion3@06,hasCode is:0
* p ***> is:5Persion3@04,hasCode is:0
* p ***> is:8Persion3@02,hasCode is:0
* p ***> is:9Persion3@05,hasCode is:0
* 按照Age进行排序
*/
Set<Persion3> sortSet = new TreeSet<Persion3>();
Persion3 pf1 = new Persion3(1);
Persion3 pf2 = new Persion3(8);
Persion3 pf3 = new Persion3(2);
Persion3 pf4 = new Persion3(5);
Persion3 pf5 = new Persion3(9);
Persion3 pf6 = new Persion3(4);
Persion3 pf7 = new Persion3(0);
sortSet.add(pf1);
sortSet.add(pf2);
sortSet.add(pf3);
sortSet.add(pf4);
sortSet.add(pf5);
sortSet.add(pf6);
sortSet.add(pf7);
for(Persion3 p:sortSet){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
/**
* Set排序,按照【排序器】进行排序Comparetor
* 打印:
* p ***> is:1Persion3@01,hasCode is:0
* p ***> is:8Persion3@02,hasCode is:0
* p ***> is:2Persion3@03,hasCode is:0
* p ***> is:5Persion3@04,hasCode is:0
* p ***> is:9Persion3@05,hasCode is:0
* p ***> is:4Persion3@06,hasCode is:0
* p ***> is:0Persion3@07,hasCode is:0
* 按照index进行排序
*/
TreeSet<Persion3> sortSetByComparator = new TreeSet<Persion3>(new ComparetorByIndex());
sortSetByComparator.add(pf1);
sortSetByComparator.add(pf2);
sortSetByComparator.add(pf3);
sortSetByComparator.add(pf4);
sortSetByComparator.add(pf5);
sortSetByComparator.add(pf6);
sortSetByComparator.add(pf7);
for(Persion3 p:sortSetByComparator){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
}
}
class Persion1{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion1(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion1){
Persion1 p = (Persion1)arg0;
return mAge == p.mAge;
}
return super.equals(arg0);
}
}
class Persion2{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion2(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion2){
Persion2 p = (Persion2)arg0;
return mAge != p.mAge;
}
return super.equals(arg0);
}
}
class Persion3 implements Comparable<Persion3>{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion3(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion3){
Persion3 p = (Persion3)arg0;
return mAge != p.mAge;
}
return super.equals(arg0);
}
@Override
public int compareTo(Persion3 p) {
return mAge - p.mAge ;
}
}
class ComparetorByAge implements Comparator<Persion3>{
@Override
public int compare(Persion3 p0, Persion3 p1) {
return p0.mAge - p1.mAge;
}
}
class ComparetorByIndex implements Comparator<Persion3>{
@Override
public int compare(Persion3 p0, Persion3 p1) {
return p0.index - p1.index;
}
}
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<Persion1> set1 = new HashSet<Persion1>();
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<Persion2> set2 = new HashSet<Persion2>();
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");
Iterator<Persion1> iterator = set3.iterator();
while(iterator.hasNext()){
Object p = iterator.next();
System.out.println("p ---->"+p+",hasCode is:"+p.hashCode());
}
System.out.println("*********************************************");
//-------------------------------------------
/**
* LinkedHashSet 根据哈希码进行存放,同时用链表记录元素的加入顺序。
* 通过链表存储对象,一般插入和删除效率较高,检索效率较低。
*/
LinkedHashSet linkedSet = new LinkedHashSet();
/**
* LinkedHashSet记录元素加入顺序
*
*/
Persion1 pd1 = new Persion1(55);
Persion1 pd2 = new Persion1(66);
Persion1 pd3 = new Persion1(77);
Persion1 pd4 = new Persion1(88);
linkedSet.add(pd1);
linkedSet.add(pd2);
linkedSet.add(pd3);
linkedSet.add(pd4);
linkedSet.add("aaaa");
linkedSet.add("bbbb");
linkedSet.add("cccc");
for(Object p:linkedSet){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
//-------------------------------------------
/**
* 有多个不同类型的对象加入TreeSet,就会报异常。
* 对于自定义的类,它的对象只能存放一个,而且实现类不需要实现【Comparable接口】。
* 但是,如果 想要存放多个自定义的类的对象,
* 不实现Comparable接口就会发生java.lang.ClassCastException异常 。
*/
Set treeSet = new TreeSet();
Persion1 pe1 = new Persion1(12);
treeSet.add(pe1);
/*treeSet.add(new String("hello"));*/
Iterator itor = treeSet.iterator();
while(itor.hasNext()){
System.out.println("TreeSet p is:"+itor.next());
}
System.out.println("---------------------------------------");
//-------------------------------------------
/**
* Set排序
* Persion3实现了排序的接口Comparable
*/
Set<Persion3> sortSet = new TreeSet<Persion3>();
Persion3 pf1 = new Persion3(1);
Persion3 pf2 = new Persion3(8);
Persion3 pf3 = new Persion3(2);
Persion3 pf4 = new Persion3(5);
Persion3 pf5 = new Persion3(9);
Persion3 pf6 = new Persion3(4);
Persion3 pf7 = new Persion3(0);
sortSet.add(pf1);
sortSet.add(pf2);
sortSet.add(pf3);
sortSet.add(pf4);
sortSet.add(pf5);
sortSet.add(pf6);
sortSet.add(pf7);
for(Persion3 p:sortSet){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
/**
* Set排序,按照【排序器】进行排序Comparetor
*/
TreeSet<Persion3> sortSetByComparator = new TreeSet<Persion3>(new ComparetorByIndex());
sortSetByComparator.add(pf1);
sortSetByComparator.add(pf2);
sortSetByComparator.add(pf3);
sortSetByComparator.add(pf4);
sortSetByComparator.add(pf5);
sortSetByComparator.add(pf6);
sortSetByComparator.add(pf7);
for(Persion3 p:sortSetByComparator){
System.out.println("p ***> is:"+p+",hasCode is:"+p.hashCode());
}
System.out.println("---------------------------------------");
}
}
class Persion1{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion1(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion1){
Persion1 p = (Persion1)arg0;
return mAge == p.mAge;
}
return super.equals(arg0);
}
}
class Persion2{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion2(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion2){
Persion2 p = (Persion2)arg0;
return mAge != p.mAge;
}
return super.equals(arg0);
}
}
class Persion3 implements Comparable<Persion3>{
public int mAge;
private static AtomicInteger atIndex = new AtomicInteger();//原子类型
public int index;
public Persion3(int age){
mAge = age;
index = atIndex.addAndGet(1);
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return mAge+""+super.toString()+index;
}
@Override
public boolean equals(Object arg0) {
if(arg0 instanceof Persion3){
Persion3 p = (Persion3)arg0;
return mAge != p.mAge;
}
return super.equals(arg0);
}
@Override
public int compareTo(Persion3 p) {
return mAge - p.mAge ;
}
}
class ComparetorByAge implements Comparator<Persion3>{
@Override
public int compare(Persion3 p0, Persion3 p1) {
return p0.mAge - p1.mAge;
}
}
class ComparetorByIndex implements Comparator<Persion3>{
@Override
public int compare(Persion3 p0, Persion3 p1) {
return p0.index - p1.index;
}
}