JAVA 集合
Posted 不该相遇在秋天
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.集合中只能存储对象,当你存储基本类型时,它会自动装箱再存储,同理,用基本类型接收时,会有自动拆箱的过程。
源码分享
以上是关于JAVA 集合的主要内容,如果未能解决你的问题,请参考以下文章