Java容器有哪些——集合

Java容器分为Collection和Map两大类,其下又有很多子类

 

一:Iterable 接口

1:Iterable 是一个超级接口 被collection所继承,它只有一个方法:Iterator<T> iterator();      //返回一个迭代器。

2:迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象。迭代器被称为‘轻量级’对象,因为创建代价小。

3:Java中的Iterator功能比较简单,并且只能单向移动:
  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
  (2) 使用next()获得序列中的下一个元素。
  (3) 使用hasNext()检查序列中是否还有元素。
  (4) 使用remove()将迭代器新返回的元素删除。

4:Iterator是Java迭代器最简单的实现。像遍历集合就是迭代器的使用。

 

二:Collection接口

1:List 接口

1):List 是有序的,用户可以根据元素的索引访问元素。

2):List 可以插入重复的值。

3):List 接口提供了特殊的迭代器——ListIterator,除了允许Iterator接口提供正常操作外,该迭代器还允许元素插入和替换,以及双向访问。

4):List 的子类—— List 的实现类,有:ArrayList、LinkedList、Vector,

4-1):ArrayList 

                  1:是基于数组实现的List 类,它封装了一个动态的、增长的、允许再分配的Object[] 数组,它允许对元素快速的随机访问。(线程不安全)

                  2:当从ArrayList中间位置插入或删除元素时,需要对数组复制、移动、代价比较高,因为它适合随机查找和遍历,不适合插入和删除。

4-2):LinkedList 

                  1:是用双向链表结构存储数据的(线性的存储方式),很适合动态数据的添加和删除。随机访问和遍历速度比较慢。

                  2:它还实现Deque接口,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。

4-3):Vector 

                  1:也是通过数组实现,它支持线程的同步,线程安全,即某一个时刻只能有一个线程能够写Vector,避免多线程同时写入而引起的不一致性。

                       但实现同步需要花费很高的代价, 因此,访问它比访问ArrayList慢。所以,现在已不常用。

                  2:Stack 类,Stock 是Vector 提供的一个子类,用于模拟 “栈” 这种数据结构(LIFO后进先出)

List 接口的排序可以通过Collections.sort() 来排序。只需要继承Compareble接口后,重写 compareTo() 方法

2:Set 接口

1):Set 要满足无序性、确定性、单一性,所以Set 是无序、不可重复的,Set 只有有一个null

2):Set 判断两个对象相同不是使用 == 运算符,而是用 equals方法,

3):Set 的子类—— Set的实现类,有:HashSet、TreeSet、LinkedHashSet(从HashSet继承而来)

3-1):HashSet 使用HASH算法来存储集合中的元素,因此具有良好存储和查找性能。当往HashSet 存值时,HashSet会调用该对象的 hashCode() 方法得到该对象 hashCode 值,

            然后根据 hashCode 值决定该对象存放在 HashSet 中的存储位置。HashSet 是用equals来判断两个元素是否相等的,并且两个对象的hashCode() 方法的返回值相等。

            HashSet 的实现原理:HashSet是基于HashMap实现的,HashSet 底层使用HashMap来保存元素的,HashSet不允许有重复的值。

3-1-1):LinkedHashSet(类) 集合也是根据hashCode值来决定存放的位置,和HashSet不同的是,它同时使用链表维护元素的次序,

3-2):StoredSet 接口,此接口主要用于排序,实现此接口的子类都属于排序的子类。 TreeSet 是StoredSet的实现类,TreeSet 可以确保集合元素处于排序状态 。

3-3):EnumSet 是一个专门为枚举设计的类,EnumSet中的所有元素必须是指定枚举类型的枚举值,

3:Queue

1):Queue 用于模拟 “队列” 数据结构(FIFO),新插入的元素放入队尾,对头存在保存时间最长的元素。

2):PriorityQueue 类 ——优先队列,它不是按照插入顺序来存放元素的,而是按照队列中某个属性的大小来排列的,故而叫优先队列。

3):Deque 接口 —— 双端对列,

3-1):ArrayDeque(类),基于数组的双端队列,类似于ArrayList有一个Object[] 数组。

3-2):LinkedList (类),参考上文介绍。

简单回顾一下上述三个接口的区别

容器名是否有序是否可重复null的个数
List有序可重复允许多个null
Set无序不可重复只允许一个null
Queue有序(FIFO)可重复通常不允许插入null

 

三:Map接口,Map的子类、子接口

       Map是一个接口。Map用于保存具有映射关系的数据,每个Entry都有key-value两个对象,value可以重复,key不可重复。Map可以有多个value为null,只能有一个key为null。

1:HashMap (类)

1):HashMap 和HashSet一样不能保证元素的顺序  HashMap也不能保证key-value的顺序。HashMap 也是通过equals() 方法比较

2):LinkedHashMap(类),使用双向链表结构来维护key-value对的次序。

3):非线程安全

4):实现原理——基于hash算法实现,当传入key时,HashMap会根据key.hashCode() 计算出key的hash值,然后把值保存到bucket里,当计算出的hash值相同时,我们称之为

         hash冲突,HashMap的做法是用链表和红黑树存储相同的hash值的value。当hash 冲突比较少时,使用链表,否则使用红黑树。

5):数据结构是:数据+链表+红黑树

2:HashTable (类)

1):是一个古老的Map实现类

2):Properties(类)对象在处理属性文件特别方便(windows平台的.ini文件)。Properties类可以把Map对象和属性文件关联,从而把Map的key-value对写入到属性文件中,

         也可以把属性文件中的“属性名-属性值”加载进Map对象中。

3):线程安全

3:SortedMap(接口),实现接口类是TreeMap

1):如同Set->SortedSet->TreeSet一样,Map也有Map->SortedMap->TreeMap的继承关系。

2):TreeMap(类) 是一个红黑树结构,每个键值对都作为一个红黑树的节点。TreeMap存储键值对时,需要根据key对节点进行排序,TreeMap可以保证所有的key-value对

         处于有序状态。同时,TreeMap 有两种排序方式:自然排序、定制排序。

4:WeakHashMap

 

5: IdentityHashMap(类)

 

6:EnumMap(类)

 

 

常见问题:

1:ArrayList 和 LinkedList 的区别是什么?

1):数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。

2):随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。

3):增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList增删操作要影响数组内的其他数据的下标。

4):综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。

2:如何实现数组和 List 之间的转换?

1):数组转 List:使用 Arrays. asList(array) 进行转换。

2):List 转数组:使用 List 自带的 toArray() 方法。

3:ArrayList 和 Vector 的区别是什么?

1):线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。

2):性能:ArrayList 在性能方面要优于 Vector。

3):扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次会增加 1倍,而 ArrayList 只会增加 50%

4:Array 和 ArrayList 有何区别?

1):Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。

2):Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。

3):Array 内置方法没有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。

5:在 Queue 中 poll()和 remove()有什么区别?

1):相同点:都是返回第一个元素,并在队列中删除返回的对象。

2):不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。

代码示例:

Queue queue = new LinkedList();
queue. offer(“string”); // add
System. out. println(queue. poll());
System. out. println(queue. remove());
System. out. println(queue. size());

6:哪些集合类是线程安全的?

Vector、Hashtable、Stack 都是线程安全的,而像 HashMap 则是非线程安全的,不过在 JDK 1.5 之后随着 Java. util. concurrent 并发包的出现,它们也有了自己对应的线程安全类,比如 HashMap 对应的线程安全类就是 ConcurrentHashMap。

7:Iterator 和 ListIterator 有什么区别?

1):Iterator 可以遍历 Set 和 List 集合,而 ListIterator 只能遍历 List。

2):Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。

3):ListIterator 从 Iterator 接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

8:怎么确保一个集合不能被修改?

1):可以使用 Collections.unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都是抛出Java.lang.UnsupportedOperationException 异常。

2):示例代码如下:

                List list = new ArrayList<>();
                       list. add(“x”);
                       Collection clist = Collections. unmodifiableCollection(list);   //把集合变成只读集合
                       clist. add(“y”); // 运行时此行报错
                       System. out. println(list. size());

9:Arrays.sort 和 Collections.sort 实现原理 和区别

1:collection 和 collections 的区别:

1.1:java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。

1.2:java.util.Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作。 然后还有混排(Shuffling)、反转(Reverse)、替换所有的元素(fill)、拷贝(copy)、返回Collections中最小元素(min)、返回Collections中最大元素(max)、返回指定源列表中最后一次出现指定目标列表的起始位置( lastIndexOfSubList )、返回指定源列表中第一次出现指定目标列表的起始位置( IndexOfSubList )、根据指定的距离循环移动指定列表中的元素(Rotate);

1.3:事实上Collections.sort方法底层就是调用的array.sort方法。






 

 

 

 

 

 

 

                                                                                                            Collection

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值