java set 操作_Java Set操作

Set:无顺序,不包含重复的元素

HashSet:为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。

TreeSet: 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。

LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

HashSet:

importjava.util.HashSet;importjava.util.Iterator;public classMain {public static voidmain(String[] args) {

HashSet set= newHashSet();//分别向books集合中添加两个A对象,两个B对象,两个C对象

set.add(newA());

set.add(newA());

set.add(newB());

set.add(newB());

set.add(newC());

set.add(newC());

System.out.println(set);

System.out.println(set.size());for(Iterator iter =set.iterator(); iter.hasNext();){

Object value=iter.next();

System.out.println(value);

}

}

}//类A的equals方法总是返回true,但没有重写其hashCode()方法。不能保证当前对象是HashSet中的唯一对象

classA

{public booleanequals(Object obj)

{return true;

}

}//类B的hashCode()方法总是返回1,但没有重写其equals()方法。不能保证当前对象是HashSet中的唯一对象

classB

{public inthashCode()

{return 1;

}

}//类C的hashCode()方法总是返回2,且有重写其equals()方法

classC

{public inthashCode()

{return 2;

}public booleanequals(Object obj)

{return true;

}

}

Result:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

[com.qhong.B@1, com.qhong.B@1, com.qhong.C@2, com.qhong.A@677327b6, com.qhong.A@1540e19d]5com.qhong.B@1com.qhong.B@1com.qhong.C@2com.qhong.A@677327b6

com.qhong.A@1540e19d

View Code

B类的hashcode值一样,但是没有定义equals,所以存储了两个对象,但是对象因为hashcode一样,存储位置也一样,两个对象按链表方式存储。

C类中hashcode值一样,equals也一样,所以只能存储一个值。

A类中没有定义hashcode,所以存储位置不一样,这里还没有进行equals对比,一样存储两个对象。

LinkedHashSet

importjava.util.Iterator;importjava.util.LinkedHashSet;public classMain {public static voidmain(String[] args) {

LinkedHashSet books= newLinkedHashSet();

books.add("Java1");

books.add("Java2");

System.out.println(books);//删除 Java

books.remove("Java1");//重新添加 Java

books.add("Java1");

System.out.println(books);for(Iterator iter =books.iterator(); iter.hasNext();){

Object value=iter.next();

System.out.println(value);

}

}

}

Result:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

[Java1, Java2]

[Java2, Java1]

Java2

Java1

View Code

元素的顺序总是与添加顺序一致,LinkedHashSetTest是HashSet的子类,因此它不允许集合元素重复.

TreeSet:

importjava.util.TreeSet;public classMain {public static voidmain(String[] args) {

TreeSet nums= newTreeSet();//向TreeSet中添加四个Integer对象

nums.add(5);

nums.add(2);

nums.add(10);

nums.add(-9);//输出集合元素,看到集合元素已经处于排序状态

System.out.println(nums);//输出集合里的第一个元素

System.out.println(nums.first());//输出集合里的最后一个元素

System.out.println(nums.last());//返回小于4的子集,不包含4

System.out.println(nums.headSet(4));//返回大于5的子集,如果Set中包含5,子集中还包含5

System.out.println(nums.tailSet(5));//返回大于等于-3,小于4的子集。

System.out.println(nums.subSet(-3 , 4));

}

}

Result:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

[-9, 2, 5, 10]-9

10[-9, 2]

[5, 10]

[2]

View Code

与HashSet集合采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。

TreeSet支持两种排序方式: 自然排序、定制排序

TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序排序,即自然排序。

通过ComparaTor接口可以实现定制排序。

importjava.util.Comparator;importjava.util.Iterator;importjava.util.TreeSet;public classMain {public static voidmain(String[] args) {

TreeSet ts= new TreeSet(newComparator()

{//根据M对象的age属性来决定大小

public intcompare(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(-3));

ts.add(new M(9));

System.out.println(ts);for(Iterator iter =ts.iterator(); iter.hasNext();){

Object value=iter.next();

System.out.println(value);

}

}

}classM

{intage;public M(intage)

{this.age =age;

}publicString toString()

{return "M[age:" + age + "]";

}

}

Result:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

[M[age:9], M[age:5], M[age:-3]]

M[age:9]

M[age:5]

M[age:-3]

View Code

EnumSet:

importjava.util.EnumSet;public classMain {public static voidmain(String[] args) {//创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值

EnumSet es1 = EnumSet.allOf(Season.class);//输出[SPRING,SUMMER,FALL,WINTER]

System.out.println(es1);//创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。

EnumSet es2 = EnumSet.noneOf(Season.class);//输出[]

System.out.println(es2);//手动添加两个元素

es2.add(Season.WINTER);

es2.add(Season.SPRING);//输出[SPRING,WINTER]

System.out.println(es2);//以指定枚举值创建EnumSet集合

EnumSet es3 =EnumSet.of(Season.SUMMER , Season.WINTER);//输出[SUMMER,WINTER]

System.out.println(es3);

EnumSet es4=EnumSet.range(Season.SUMMER , Season.WINTER);//输出[SUMMER,FALL,WINTER]

System.out.println(es4);//新创建的EnumSet集合的元素和es4集合的元素有相同类型,//es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值

EnumSet es5 =EnumSet.complementOf(es4);//输出[SPRING]

System.out.println(es5);

}

}enumSeason

{

SPRING,SUMMER,FALL,WINTER

}

Result:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

[SPRING, SUMMER, FALL, WINTER]

[]

[SPRING, WINTER]

[SUMMER, WINTER]

[SUMMER, FALL, WINTER]

[SPRING]

View Code

Set集合类应用场景:

1) HashSet的性能总是比TreeSet好(特别是最常用的添加、查询元素等操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序。只有当需要一个保持排序的Set时,才应该使用TreeSet,否则都应该使用HashSet2) 对于普通的插入、删除操作,LinkedHashSet比HashSet要略慢一点,这是由维护链表所带来的开销造成的。不过,因为有了链表的存在,遍历LinkedHashSet会更快3) EnumSet是所有Set实现类中性能最好的,但它只能保存同一个枚举类的枚举值作为集合元素4) HashSet、TreeSet、EnumSet都是"线程不安全"的,通常可以通过Collections工具类的synchronizedSortedSet方法来"包装"该Set集合。

SortedSet s= Collections.synchronizedSortedSet(new TreeSet(...));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值