java容器类添加元素失败失败_java容器 Set

Set的简介

Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。

在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。

HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;

TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;

常用方法

与List接口一样,Set接口也提供了集合操作的基本方法。

但与List不同的是,Set还提供了equals(Object o)和hashCode(),供其子类重写,以实现对集合中插入重复元素的处理;

HashSet

简介

HashSet实现Set接口,底层由HashMap来实现,为哈希表结构,新增元素相当于HashMap的key,value默认为一个固定的Object。当有元素插入的时候,会计算元素的hashCode值,将元素插入到哈希表对应的位置中来;它继承于AbstractSet,实现了Set, Cloneable, Serializable接口。

HashSet继承AbstractSet类,获得了Set接口大部分的实现,减少了实现此接口所需的工作,实际上是又继承了AbstractCollection类;

HashSet实现了Set接口,获取Set接口的方法,可以自定义具体实现,也可以继承AbstractSet类中的实现;

HashSet实现Cloneable,得到了clone()方法,可以实现克隆功能;

HashSet实现Serializable,表示可以被序列化,通过序列化去传输,典型的应用就是hessian协议。

特点

不允许出现重复因素;

允许插入Null值;

元素无序(添加顺序和遍历顺序不一致);

线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;

基本操作

HashSet底层由HashMap实现,插入的元素被当做是HashMap的key,根据hashCode值来确定集合中的位置,由于Set集合中并没有角标的概念,所以并没有像List一样提供get()方法。当获取HashSet中某个元素时,只能通过遍历集合的方式进行equals()比较来实现;

public class HashSetTest {

public static void main(String[] agrs){

//创建HashSet集合:

Set hashSet = new HashSet();

System.out.println("HashSet初始容量大小:"+hashSet.size());

//元素添加:

hashSet.add("my");

hashSet.add("name");

hashSet.add("is");

hashSet.add("jiaboyan");

hashSet.add(",");

hashSet.add("hello");

hashSet.add("world");

hashSet.add("!");

System.out.println("HashSet容量大小:"+hashSet.size());

//迭代器遍历:

Iterator iterator = hashSet.iterator();

while (iterator.hasNext()){

String str = iterator.next();

System.out.println(str);

}

//增强for循环

for(String str:hashSet){

if("jiaboyan".equals(str)){

System.out.println("你就是我想要的元素:"+str);

}

System.out.println(str);

}

//元素删除:

hashSet.remove("jiaboyan");

System.out.println("HashSet元素大小:" + hashSet.size());

hashSet.clear();

System.out.println("HashSet元素大小:" + hashSet.size());

//集合判断:

boolean isEmpty = hashSet.isEmpty();

System.out.println("HashSet是否为空:" + isEmpty);

boolean isContains = hashSet.contains("hello");

System.out.println("HashSet是否为空:" + isContains);

}

}

元素不重复的原理

在向HashMap中添加元素时,先判断key的hashCode值是否相同,如果相同,则调用equals()、==进行判断,若相同则覆盖原有元素;如果不同,则直接向Map中添加元素;

TreeSet

此集合的实现和树结构有关。与HashSet集合类似,TreeSet也是基于Map来实现,其底层结构为红黑树;

特点

与HashSet不同的是,TreeSet具有排序功能,分为自然排序(123456)和自定义排序两类,默认是自然排序;在程序中,我们可以按照任意顺序将元素插入到集合中,等到遍历时TreeSet会按照一定顺序输出--倒序或者升序

对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);

底层使用红黑树结构,而不是哈希表结构;

允许插入Null值;

不允许插入重复元素;

线程不安全;

接口

它继承AbstractSet,实现NavigableSet, Cloneable, Serializable接口

与HashSet同理,TreeSet继承AbstractSet类,获得了Set集合基础实现操作;

TreeSet实现NavigableSet接口,而NavigableSet又扩展了SortedSet接口。这两个接口主要定义了搜索元素的能力,例如给定某个元素,查找该集合中比给定元素大于、小于、等于的元素集合,或者比给定元素大于、小于、等于的元素个数;简单地说,实现NavigableSet接口使得TreeSet具备了元素搜索功能;

TreeSet实现Cloneable接口,意味着它也可以被克隆;

TreeSet实现了Serializable接口,可以被序列化,可以使用hessian协议来传输;

基本操作

public class TreeSetTest {

public static void main(String[] agrs){

TreeSet treeSet = new TreeSet();

System.out.println("TreeSet初始化容量大小:"+treeSet.size());

//元素添加:

treeSet.add("my");

treeSet.add("name");

treeSet.add("jiaboyan");

treeSet.add("hello");

treeSet.add("world");

treeSet.add("1");

treeSet.add("2");

treeSet.add("3");

System.out.println("TreeSet容量大小:" + treeSet.size());

System.out.println("TreeSet元素顺序为:" + treeSet.toString());

//增加for循环遍历:

for(String str:treeSet){

System.out.println("遍历元素:"+str);

}

//迭代器遍历:升序

Iterator iteratorAesc = treeSet.iterator();

while(iteratorAesc.hasNext()){

String str = iteratorAesc.next();

System.out.println("遍历元素升序:"+str);

}

//迭代器遍历:降序

Iterator iteratorDesc = treeSet.descendingIterator();

while(iteratorDesc.hasNext()){

String str = iteratorDesc.next();

System.out.println("遍历元素降序:"+str);

}

//元素获取:实现NavigableSet接口

String firstEle = treeSet.first();//获取TreeSet头节点:

System.out.println("TreeSet头节点为:" + firstEle);

// 获取指定元素之前的所有元素集合:(不包含指定元素)

SortedSet headSet = treeSet.headSet("jiaboyan");

System.out.println("jiaboyan节点之前的元素为:"+headSet.toString());

//获取给定元素之间的集合:(包含头,不包含尾)

SortedSet subSet = treeSet.subSet("1","world");

System.out.println("1--jiaboan之间节点元素为:"+subSet.toString());

//集合判断:

boolean isEmpty = treeSet.isEmpty();

System.out.println("TreeSet是否为空:"+isEmpty);

boolean isContain = treeSet.contains("who");

System.out.println("TreeSet是否包含who元素:"+isContain);

//元素删除:

boolean jiaboyanRemove = treeSet.remove("jiaboyan");

System.out.println("jiaboyan元素是否被删除"+jiaboyanRemove);

//集合中不存在的元素,删除返回false

boolean whoRemove = treeSet.remove("who");

System.out.println("who元素是否被删除"+whoRemove);

//删除并返回第一个元素:如果set集合不存在元素,则返回null

String pollFirst = treeSet.pollFirst();

System.out.println("删除的第一个元素:"+pollFirst);

//删除并返回最后一个元素:如果set集合不存在元素,则返回null

String pollLast = treeSet.pollLast();

System.out.println("删除的最后一个元素:"+pollLast);

treeSet.clear();//清空集合:

}

}

使用

若是想添加自定义的类,那么就必须满足以下两点的任意一点

实现Comparetor接口,并重写compare方法

实现Comparable接口,并重写compareTo方法

调用方法的结果

结果返回大于0时,方法前面的值大于方法中的值;

结果返回等于0时,方法前面的值等于方法中的值;

结果返回小于0时,方法前面的值小于方法中的值;

LinkedHashSet

LinkedHashSet是Set集合的一个实现,具有set集合不重复的特点,同时具有可预测的迭代顺序,也就是我们插入的顺序。

并且linkedHashSet是一个非线程安全的集合。如果有多个线程同时访问当前linkedhashset集合容器,并且有一个线程对当前容器中的元素做了修改,那么必须要在外部实现同步保证数据的冥等性。

扩容方式与hashmap相同,返回结果为存储时的顺序,这是由于链表的特性,指向存储,通过hash的特性来保证唯一性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值