java base Set集合
- Set 无序,不重复
- HashSet 无序的Set
- LinkedHashSet 有序的(添加顺序)
- SortedSet //接口,抽象出TreeSet可以公用的部分
- TreeSet 可以排序的Set
- EnumSet 专为Enum类定义的集合
- HashSet 无序的Set
Set集合
- 概述:无序集合,不可重复(某些子容器支持排序)
- HashSet是Set的典型接口的实现,
- 按hash值储存集合
- 具有很好的存储型以及查找性
- 无序的,可能与添加顺序不同
- 不是同步的,多线程,必须通过代码来保证同步
- 集合元素可以是null
- 如果hashset中存在可变元素,元素一旦被修改将无法删除,就算删除全部的未修改元素在删除已修改元素也无法删除
package java集合;
import java.util.HashSet;
import java.util.Iterator;
class R{
int count;
public R(int count){
this.count = count;
}
@Override
public String toString() {
return "count:"+count+"\t";
}
@Override 重写equals方法,通过判断count确定对象是 否重复
public boolean equals(Object obj) {
if (this==obj){
return true;
}else if (obj!=null&&obj.getClass() ==R.class){
R a = (R)obj;
return this.count == a.count;
}
return false;
}
@Override
public int hashCode() {
return this.count;
}
}
public class HashSetTest02 {
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add(new R(55));
hs.add(new R(12));
hs.add(new R(32));
hs.add(new R(-1));
System.out.println(hs);
Iterator it = hs.iterator();
R first = (R)it.next();
first.count = 12;
System.out.println(hs);
hs.remove(new R(12));//移除成功
// hs.remove(new R(12));//第二次失败
System.out.println(hs.contains(new R(12))); //不包含r12
// hs.remove(new R(32)); //尝试删除被改之前 的对象,删除失败
System.out.println(hs);//修改之后的对象,无 法删除
hs.remove(first);
System.out.println(hs);//尝试删除元素修改前 的引用对象,修改失败
}
}
注意:hashSet判断两个元素是否相同是通过hashCode和equals来判断的
3. linkerHashSet
* 他是hashSet的子类,它是有序的,顺序按照加入的先后顺序
package java集合;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
//linkhashset是hashSetd的子类
//相比hashset,他是有序的,会按照元素的插入顺序保 存
//性能略微低于hashset,因为要用链表来维持顺序,
// 但是如果迭代访问set里的全部的元素时,性能还是不 错的,因为链表来维护内部的顺序
public static void main(String[] args){
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add("java");
linkedHashSet.add("python");
Iterator iterator = linkedHashSet.iterator ();
iterator.forEachRemaining (obj->System.out.println("迭代集合"+obj));
linkedHashSet.remove("java");
linkedHashSet.add("java");
Iterator iterator1 = linkedHashSet.iterator ();
iterator1.forEachRemaining (obj->System.out.println("迭代集合"+obj));
}
}
- SortedSet --> TreeSet
- 这是一个可以排序的Set,但是他们的元素必须实现Comparable接口(绝大多的基础类型的包装类都实现了)
- 提供自然排序和定制排序(自然排序无法满足某些特定的需求)
package java集合;
import java.util.Iterator;
import java.util.TreeSet;
class TreeA implements Comparable{
/*
TreeSet中被改变了的元素是无法移除的
本身没有被改变,但是与改变了之后的元素相同的元素是 可以移除的
*/
int count;
public TreeA(int count){
this.count = count;
}
public int compareTo(Object obj){
return this.count>((TreeA)obj).count?1: (this.count<((TreeA)obj).count?-1:0);
}
}
public class TreeSetTest03 {
public static void main(String[] args){
TreeSet ts = new TreeSet();
// TreeA a = new TreeA(2);
ts.add(new TreeA(5));
ts.add(new TreeA(9));
ts.add(new TreeA(4));
ts.add(new TreeA(2));
ts.add(new TreeA(100));
System.out.println(ts.size());
ts.iterator().forEachRemaining (obj->System.err.println(((TreeA)obj) .count));
TreeA ta = (TreeA) ts.last();
ta.count = 5;
ts.iterator().forEachRemaining (obj->System.out.println(((TreeA)obj) .count));
//删
System.out.println(ts.remove(new TreeA(5))) ;
ts.iterator().forEachRemaining (obj->System.out.println(((TreeA)obj) .count));
ts.remove(new TreeA(2));
ts.remove(new TreeA(4));
ts.remove(new TreeA(9));
ts.iterator().forEachRemaining (obj->System.err.println(((TreeA)obj) .count));
//将所有可删除的元素删除之后就能修改那些被改变 之后的元素了
System.out.println(ts.remove(new TreeA(5))) ;
}
}
//定制排序,需要在创建TreeSet容器的时候,参数传入定制的方法,一个Compartor的对象作为参数
package java集合;
import java.util.Comparator;
import java.util.TreeSet;
class Prople{
int age;
public Prople(int age){
this.age = age;
}
@Override
public String toString() {
return "age:"+age;
}
}
public class TreeSetTest04 {
//Tree的定制排序
public static void main(String[] args){
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Object o, Object t1) {
return ((Prople)o).age>((Prople)t1) .age?-1:((Prople)o)
.age<((Prople)t1).age?1:0;
}
});
ts.add(new Prople(1));
ts.add(new Prople(2));
ts.add(new Prople(4));
ts.add(new Prople(3));
System.out.println(ts);
}
}
- EnumSet
- 这是一个特意为枚举类制定的集合,这个集合只能容纳枚举类的元素,并且,这些枚举类的元素还必须是同一枚举类的元素
- 这个集合在创建时就需要指定,创建容易的枚举类型(或者用一个装满枚举元素的Collection类型的集合来创建EnumSet)
- 这个集合特有的方法基本就是以各种各样的姿势创建对象
//创建对象的方法大多差距甚微,这里列出几个代表性的
package java集合;
import java.util.EnumSet;
enum Season{
SPRING,SUMMER,FALL,WINTER;
}
public class EnumSetTest {
public static void main(String[] args){
//创建一个Season枚举类型的EnumSet
EnumSet es = EnumSet.noneOf(Season.class);
es.add(Season.FALL);
es.add(Season.SPRING);
es.add(Season.SUMMER);
System.out.println(es);
//[SPRING, SUMMER, FALL]
//创建一个包含指定枚举类的所有元素(Season)的 enumset
EnumSet es1 = EnumSet.allOf(Season.class);
System.err.println(es1);
//[SPRING, SUMMER, FALL, WINTER]
//创建一个包含从a到b的范围内的所有枚举值
EnumSet es2 = EnumSet.range(Season.SPRING, Season.FALL);
System.out.println(es2);
//[SPRING, SUMMER, FALL]
}
}
总结:
hashSet的性能比TreeSet的略强,TreeSet需要额外的红黑算法来维护集合元素的次序,需要一个保持排序的用TreeSet否则用hashSet
linkedHashSet,插入和删除相比hashSet会有点慢,因为要花费开销来维护链表,但是如果遍历的话,linkdHashSet会更快
EnumSet性能最好但是限制过大
声明:这些方法全部都是线程不安全的,如若有需要,可以通过Collections工具类中的方法进行包装。
白茶清欢无别事,我在等风也等你。

浙公网安备 33010602011771号