JAVA 集合
一、概念
能够存放一个或一组对象的容器,就叫做集合,他是一套功能完善的数据结构。(也叫做容器 也叫做集合框架)
二、集合一览表
集合类型 | 描述 |
arraylist | 一种可以动态增长和缩减的索引序列 |
linkedlist | 一种可以在任何位置进行高效的插入和删除操作的有序序列 |
arraydeque | 一种用循环数组实现的双端队列 |
hashset | 一种没有重复元素的无序集合 |
treeset | 一种没有重复元素的有序集合 |
enumset | 一种包含枚举类型值的集合 |
linkedhashset | 一种按照插入顺序来存储元素的集合 |
priorityqueue | 一种允许高效删除最小元素的队列集合 |
hashmap | 一种存储键值对的映射表 |
treemap | 一种有序存储键值对的映射表 |
enummap | 一种键值属于枚举类型的映射表 |
linkedhashmap | 一种按照插入顺序来存储元素的映射表 |
weakhashmap | 一种当值不再被使用时可以自动被垃圾回收器回收的映射表 |
identityhashmap | 一种用==而不是用equals比较键值的映射表 |
三、collection家族
arraylist
在java中,数组的长度是固定的,数组在创建之后,就不能增长或减小,arraylist就是用来解决这个问题的,arraylist的长度可以自动增加和减小。
arraylist a1 = new arraylist<>();//不限存储类型 啥都能往里塞 arraylist<string> a2 = new arraylist<>();//只能存储string类型 arraylist<integer> a3 = new arraylist<>(arrays.aslist(2,4,5));//将一个collection集合初始化成arraylist arraylist<integer> a4 = new arraylist<>(10);//指定初始化大小
arraylist<string> a1 = new arraylist<>(); system.out.println(a1.tostring()+" 集合长度是:"+a1.size());//output:[] 数组长度是:0 a1.add("a"); a1.add("c"); a1.add(1,"b");//指定插入位置 system.out.println(a1.tostring()+" 集合长度是:"+a1.size());//output:[a, b, c] 数组长度是:3 a1.addall(arrays.aslist("d","e","f"));//插入一个数组 system.out.println(a1.tostring()+" 集合长度是:"+a1.size());//output:[a, b, c, d, e, f] 数组长度是:6 a1.remove("a");//移除对象 a1.remove(1);//移除该索引的对象 system.out.println(a1.tostring()+" 集合长度是:"+a1.size());//output:[b, d, e, f] 数组长度是:4 //可以看出 a1一开始是空的,随着数据的插入,a1的长度在自动增长,随着数据的移除,a1的长度在自动减小。 //移除a对象后,b的索引就变成了0,所以移除索引1的对象实际上是移除了c //arraylist转数组 string a2[] = new string[a1.size()]; a2 = a1.toarray(a2); for(string a : a2){ system.out.print(" 遍历数组"+a); } //output:遍历数组b 遍历数组d 遍历数组e 遍历数组f
linkedlist
arraylist的缺陷是从中间位置删除元素要付出的代价非常大,因为处于中间被删除的元素之后的所有元素都要向列表的前端移动,从中间插入元素同理。
链表就解决了这个问题,链表中每一个对象都存在独立的节点中,每个节点拥有3个东西,一个是存储的对象,另外两个是标记,指向上一个节点和下一个节点的引用。删除数据时只需要更改标记引用即可,
linkedlist<integer> a1 = new linkedlist<>();//创建一个空链表 linkedlist<integer> a2 = new linkedlist<>(arrays.aslist(2,5,6));//将一个collection集合初始化成linkedlist
linkedlist<string> a1 = new linkedlist<>(); a1.add("a"); a1.add("c"); a1.add(1,"b");//添加到指定位置 system.out.println(a1);//output:[a, c, b] a1.addfirst("a0");//添加到头部 system.out.println(a1);//output:[a0, a, b, c] a1.addlast("d");//添加到尾部 system.out.println(a1);//output:[a0, a, b, c, d] string s1 = a1.getfirst();//获取头部元素 system.out.println(s1);//output:a0 string s2 = a1.getlast();//获取尾部元素 system.out.println(s2);//output:d string s3 = a1.get(1);//获取指定位置的元素 system.out.println(s3);//output:a a1.remove("b");//移除元素 system.out.println(a1);//output:[a0, a, c, d] a1.remove(1);//移除指定位置的元素 system.out.println(a1);//output:[a0, c, d] a1.removefirst();//移除第一个元素 system.out.println(a1);//output:[c, d] a1.removelast();//移除最后一个元素 system.out.println(a1);//output:[c]
hashset
有一种叫散列表的数据结构可以快速的查找所需要的对象,java提供了一个基于散列表的实现,hashset,它的特点是速度快,无重复。
hashset<integer> a1 = new hashset();//创建一个hashset hashset<integer> a2 = new hashset(arrays.aslist(2.5,6));//将一个collection集合初始化成hashset
hashset<integer> aa = new hashset<>(); aa.add(2); aa.add(22); aa.add(55); aa.add(23); aa.add(35); aa.add(15); aa.add(19); aa.add(6); system.out.println(aa);//output:[2, 35, 19, 22, 6, 55, 23, 15] hashset<string> a1 = new hashset<>(); a1.add("a"); a1.add("a"); a1.add("b"); a1.add("d"); a1.add("c"); system.out.println(a1);//output:[a, b, c, d] int s = a1.size(); system.out.println(s);//output:4 a1.remove("a"); system.out.println(a1);//output:[b, c, d]
可以发现 插入的顺序并不是存储的顺序,存储是无序的,但如果是说它是随机的我肯定不信,因为每次运行的打印结果都是一样的。
linkedhashset
linkedhashset扩展了hashset类,他的方法和hashset完全一样,唯一的特点是它是链表实现,他的存储顺序完全就是插入顺序。
hashset<integer> a1 = new linkedhashset<>();//创建一个linkedhashset hashset<integer> a2 = new linkedhashset(arrays.aslist(2.5,6));//将一个collection集合初始化成linkedhashset
linkedhashset<string> a1 = new linkedhashset<>(); a1.add("a"); a1.add("a"); a1.add("b"); a1.add("d"); a1.add("c"); system.out.println(a1);//output:[a, b, d, c] int s = a1.size(); system.out.println(s);//output:4 a1.remove("a"); system.out.println(a1);//output:[b, d, c]
treeset
treeset与散列集十分类似,它比散列集有所改进,树是一个有序集合,在添加元素时它会在内部进行比较排序,将元素添加到合适的位置,所以选不选用treeset的判断条件是需不需要排序
treeset<integer> a1 = new treeset<>(); treeset<integer> a2 = new treeset<>(arrays.aslist(2,5,6));
treeset<integer> a1 = new treeset<>(); a1.add(22); a1.add(53); a1.add(66); a1.add(9); a1.add(12); a1.add(27); a1.add(19); a1.add(35); system.out.println(a1);//output:[9, 12, 19, 22, 27, 35, 53, 66] treeset<integer> a2 = new treeset<>(a1.subset(10,30));//获取a1中10到30的元素 组成新树 system.out.println(a2);//[12, 19, 22, 27]
priorityqueue
优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索,它使用了一个高效的数据结构,叫做堆,堆是一个可以自我调整的二叉树,堆树执行添加和删除操作,可以让最小的元素移动到根,从而不比花费时间对元素进行排序。
priorityqueue<integer> a1 = new priorityqueue<>(); priorityqueue<integer> a2 = new priorityqueue<>(arrays.aslist(2,5,3)); priorityqueue<integer> a3 = new priorityqueue<>(comparator.reverseorder());//指定排序比较器
priorityqueue<integer> a1 = new priorityqueue<>(comparator.naturalorder()); a1.add(88); a1.add(34); a1.add(54); a1.add(26); a1.add(62); a1.add(19); system.out.println(a1);//output:[19, 34, 26, 88, 62, 54] a1.remove();//默认删除队列最前端元素 system.out.println(a1);//output:[26, 34, 54, 88, 62] a1.remove(54);//删除指定元素 system.out.println(a1);//output:[26, 34, 62, 88] a1.offer(3);//往队列出口压入元素 system.out.println(a1);//output:[3, 26, 62, 88, 34] system.out.println(a1.peek());//偷看元素 output:3 system.out.println(a1);//output:[3, 26, 62, 88, 34] system.out.println(a1.poll());//弹出元素 output:3 system.out.println(a1);//output:[26, 34, 62, 88]
四、map家族
hashmap
散列映射,hashmap实现了map接口,它使用哈希表存储映射,这使得即使对于比较大的集合,它的存取执行时间都是非常高效的。
hashmap map = new hashmap(); map.put("a","第一个元素a"); map.put("b","第二个元素b"); map.put("c","第三个元素c"); system.out.println(map); //遍历方式1 set<map.entry<string,string>> set = map.entryset(); for(map.entry<string,string> m : set){ system.out.println("key="+m.getkey()+" value="+m.getvalue()); } //遍历方式2 map.foreach((k,v)-> system.out.println("key="+k+" value="+v));
treemap
树映射,treemap也实现了map接口,它与hashmap的使用方式一样,因此就不贴重复的代码了,不同的是,treemap是默认以键的升序存储。
那么应该选择散列映射还是树映射呢?答案是散列稍微快一些,如果不需要按照排序存储,那么最好选择散列。
五、个人分享
悄悄话
1.collection 存放一行一行的数据 可以想成mysql的表 只不过这个表只有两个字段 第一个字段是索引,第二个字段是存储对象, 可以理解成索引数组
2.map 键值对 json redis 关联数组 怎么理解都没错
3.集合中只能存储对象,当你存储基本类型时,它会自动装箱再存储,同理,用基本类型接收时,会有自动拆箱的过程。
源码分享
上一篇: 楼上妹纸的小内内掉我家阳台了
下一篇: 上班无聊的时候