大家好,今天小编来为大家解答Java面试热点解析:深入集合框架(第二部分)这个问题,很多人还不知道,现在让我们一起来看看吧!
布尔值包含(对象o)
布尔值isEmpty()
布尔等于(对象obj)
迭代器iterator()
布尔删除(对象o)
布尔值removeAll(集合?c)
整数大小()
Object[] toArray()T[] toArray(T[] a) 关于集合族,有这样的描述:
Set 接口没有明确要求元素是有序的还是无序的。 Set 接口有一个名为SortedSet 的子接口,可用于对Set 元素进行排序。 SortedSet 有一个名为NavigableSet 的子接口。该接口定义的方法可以在有序Set中查找、遍历。 Jdk类库中实现Set接口的主要类有:AbstractSet、HashSet、TreeSet、EnumSet、LinkedHashSet等,其中HashSet和TreeSet都是AbstractSet的子类。 Java官方文档中提到HashSet和TreeSet分别是基于HashMap和TreeMap实现的(后面我们会简单介绍HashMap和TreeMap)。它们之间的区别在于,Set接口是一组对象(数学意义上的“集合”),而Map是键值对的集合。 Queue 接口Queue 接口是队列数据结构的抽象。一般队列实现允许我们高效地将元素添加到队列末尾并从队列头部删除元素(先进先出)。 Queue 接口还有一个名为Deque 的子接口,它允许我们高效地添加/删除队列头部或尾部的元素。实现Deque接口的集合类是双端队列的实现(例如LinkedList实现了Deque接口)。实现Queue接口的类主要有:AbstractQueue、ArrayDeque、LinkedList、PriorityQueue、DelayQueue等。
Queue 接口定义了以下方法: boolean add(E e) //向队列添加一个元素。如果队列已满,则会抛出IllegalStateException。
E element() //获取头元素
boolean Offer(E e) //向队列添加一个元素,队列满则返回false
E peek() //获取队列头元素,如果队列为空则返回null
E poll() //返回并移除队列头元素,如果队列为空则返回null
Eremove() //返回并移除头部元素add和offer、element和peek、remove和poll似乎是功能相同的三对方法。它们之间的重要区别在于,前者如果操作失败会抛出异常,而后者如果操作失败则会体现在返回值中(如返回false 或null)。我们可以根据具体需要调用前者或后者。
地图界面
Java 官方文档将其定义如下:将键映射到值的对象。映射不能包含重复的键;每个键最多可以映射到一个值。Map
接口提供了三个集合视图,允许将映射的内容视为一组键、一组值或一组键值映射。映射的顺序定义为映射集合视图上的迭代器返回其元素的顺序。一些地图实现,例如TreeMap
类,对其顺序作出具体保证;其他的,比如HashMap
类,不。
大致意思是:将键映射到值的对象称为Map对象。映射表不能包含重复的键,每个键最多可以关联一个值。
Map接口提供了三种集合视图(下面我们会提到集合视图的概念):键的集合视图、值的集合视图和键值对的集合视图。
映射的顺序取决于其集合视图的迭代器返回元素的顺序。 Map接口的一些具体实现是(比如TreeMap)、保证元素有一定的顺序,其他实现是(比如HashMap)和不保证元素在其内部有序。
Map 接口允许我们快速检索与键关联的值。也就是说,利用这个特性,在Struts2框架中使用ContextMap作为容器来封装一次请求所需的所有数据。我们首先看一下Map接口定义的方法:
无效清除()
boolean containsKey(Object key) //判断是否包含指定的key
boolean containsValue(Object value) //判断是否包含指定值
布尔值isEmpty()
V get(Object key) //返回指定键映射的值
V put(K key, V value) //放入指定的键值对
V 删除(对象键)
整数大小()
SetentrySet()
设置键设置()
Collectionvalues()Map接口的具体实现类主要包括:AbstractMap、EnumMap、HashMap、LinkedHashMap、TreeMap。哈希表。
我们看一下HashMap的官方定义:HashMap是Map接口基于哈希表数据结构的具体实现,允许空键和空值。该类大致相当于HashTable,只不过HashMap 不是线程安全的并且允许null 键和null 值。由于它是基于哈希表实现的,因此HashMap内部的元素是无序的。 HashMap对和get、put操作的时间复杂度是常数级(统一哈希的前提下)。迭代HashMap 的集合视图所需的时间与HashMap 的容量(桶的数量)加上HashMap 的大小(键值对的数量)成正比。因此,如果迭代操作的性能很重要,请勿将初始容量设置得太高(并且不要将负载因子设置得太低)。
影响HashMap对象性能的因素有两个:初始容量(initialcapacity)和负载因子(loadfactor)。初始容量是HashMap对象第一次创建时内部哈希表中“桶”的数量(请参考哈希表的定义)。负载因子等于maxSize/capacity,即HashMap允许的最大键值对数量与桶数量的比值。增加负载因子可以节省空间,但查找元素的时间会增加。降低负载因子会占用更多的存储空间,但get和put操作会更快。当HashMap中的键值对数量超过maxSize(即负载因子和容量的乘积)时,就会重新进行哈希处理,重新哈希会重建内部数据结构,桶的数量(容量)将大约增加一倍。
HashMap的构造函数如下:
哈希映射()
HashMap(int 初始容量)
HashMap(int 初始容量,浮点loadFactor)
HashMap(Map? extends K, extends Vm) //创建一个新的HashMap,并用m的数据填充它。常用方法如下:
无效清除()
布尔值containsKey(对象键)
布尔包含值(对象值)
V get(对象键)
V put(K键,V值)
布尔值isEmpty()
V 删除(对象键)
整数大小()
收藏值()
SetentrySet()
SetkeySet()的功能非常直观。更多使用细节请参考Java官方文档,这里不再贴出。这里简单提一下WeakHashMap。它与HashMap的区别在于,它存储的键是“弱引用”,即当WeakHashMap中不再有外部引用该键时,对应的键值就会被回收。 WeakHashMap等类的具体使用和注意事项可以参考官方文档。
下面简单介绍一下另一个Map接口——TreeMap的具体实现。
它的官方定义是这样的:TreeMap是一个基于红黑树的Map接口实现。TreeMap中的元素的有序的,排序是根据其中存储的键的自然顺序(自然顺序,即数字从小到大,字母按字典顺序)或者根据创建TreeMap时提供的Comparator对象,具体取决于哪个一种是使用构造函数。 TreeMap的containsKey、get、put和remove操作的时间复杂度是log(n)。
TreeMap 有以下构造函数:
TreeMap() //使用自然顺序对其元素进行排序
TreeMap(Comparator? super Kcomparator) //使用比较器对其元素进行排序
TreeMap(Map? extends K, extends Vm) //构造一个包含与映射表m相同元素的TreeMap,并按照自然顺序排列
TreeMap(SortedMapm) //构造一个TreeMap,其中包含与有序映射表m相同的元素和元素顺序
其常用方法如下:
K天花板钥匙(K键)
无效清除()
比较器? super Kcomparator() //返回使用的比较器,如果按自然顺序则返回null
布尔值containsKey(对象键)
布尔包含值(对象值)
NavigableSetdescendingKeySet() //按照TreeMap中包含的键的相反顺序返回一个NavigableSet视图
NavigableMapdescendingMap()
SetentrySet()
Map.EntryfirstEntry() //返回键最小的键值对
Map.EntryfloorEntry(K key) //返回与指定键最接近且小于等于它的键值对。
K楼层钥匙(K键)
V get(对象键)
设置键设置()
Map.EntrylastEntry() //返回最大的key关联的键值对
KlastKey()建议读者先了解红黑树数据结构的原理和实现(请参考算法(第四版)(豆瓣)),然后阅读官方文档中对该类的介绍,以便轻松学会,事半功倍。
我们简单介绍一下NavigableMap接口:实现该接口的类支持一些导航方法,比如lowerEntry(返回小于指定key的最大key关联的键值对)、floorEntry(返回小于指定key的最大key关联的键值对)、floorEntry(返回小于指定key的最大key关联的键值对)等。小于或等于指定键的最大键)、ceilingEntry(返回大于或等于指定键的最小键关联的键值对)和higerEntry(返回与大于指定键的最小键)。 NavigableMap 支持按升序或降序遍历或访问存储在其中的键。 NavigableMap接口还定义了firstEntry、pollFirstEntry、lastEntry和pollLastEntry等方法来准确获取指定位置的键值对。
总的来说,NavigableMap接口,顾名思义,支持我们在映射表中“自由导航”,向前或者向后迭代其中的元素,获取我们需要的指定位置的元素。 TreeMap 实现了这个接口。
视图和包装器
Java中的集合视图是一个“窗口”,用于查看集合中的全部或部分数据。然而,通过视图,我们不仅可以查看对应集合中的元素,对视图的操作也可能会影响对应的集合。例如,TreeMap和HashMap的keySet()方法将返回相应映射表对象的视图。通过使用视图,您可以获得实现Map接口或Collection接口的其他对象。
也就是说,keySet方法返回的视图是一个实现Set接口的对象,这个对象包含了一系列的key对象。轻质包装纸
Arrays.asList 方法包装Java 数组集合视图(实现List 接口)。请看下面的代码: public static void main(String[] args) {
String[] strings={"第一", "第二", "第三"};
ListstringList=Arrays.asList(strings);
字符串s1=stringList.get(0);
System.out.println(s1);
stringList.add(0, "新的第一个");
}注意:上面的代码会编译成功,但是在运行时会抛出UnsupportedOperationException,因为调用了改变列表大小的add方法。封装Arrays.asList方法返回的底层数组的集合视图不支持调用更改数组大小的方法(例如add方法和remove方法)(但可以更改数组中的元素)。
子范围
许多集合类型创建称为子范围的集合视图。例如,以下代码提取组中第10 到第19 个元素(从0 开始计数)形成子范围: List subgroup=group.subList(10, 20); //group是一个集合List接口,实现了List接口。定义的操作可以应用于子范围,包括更改列表大小的操作。例如,以下方法将清除子组列表,并且组中相应的元素也会从列表中删除:
子组.clear();对于实现SortedSet接口的有序集或者实现SortedMap接口的有序映射表,我们还可以为它们创建子范围。 SortedSet接口定义了以下三个方法:
SortedSetsubSet(E from, E to);
SortedSetheadSet(E to);
SortedSettailSet(E from);SortedMap也定义了类似的方法:
SortedMapsubMap(K from, K to);
SortedMapheadMap(K 到);
SortedMaptailMap(K from);不可修改的视图
Collections 类中的某些方法可以返回不可修改的视图: Collections.unmodifyingCollection
Collections.unmodifierList
Collections.unmodifierSet
Collections.unmodifierSortedSet
Collections.unmodifierMap
Collections.unmodifyingSortedMap 同步视图
如果集合可能被多个线程并发访问,那么我们需要保证集合中的数据不会被破坏。 Java类库的设计者使用视图机制来确保常规集合是线程安全的。例如,我们可以调用以下方法使任何实现Map接口的集合成为线程安全的:
Mapmap=Collections.synchronizedMap(new HashMap());集合视图的本质集合视图本身不包含任何数据,它只是相应界面的包装。集合视图支持的所有操作都是通过访问其关联的集合类实例来实现的。我们看一下HashMap的keySet方法的源码:
公共SetkeySet() {
塞克斯;
返回(ks=keySet)==null ? (keySet=new KeySet()) : ks;
}
最终类KeySet 扩展AbstractSet{
公共最终int 大小() {
返回大小;
}
公共最终无效清除(){
HashMap.this.clear();
}
公共最终迭代器(){
返回新的KeyIterator();
}
公共最终布尔包含(对象o){
返回containsKey(o);
}
公共最终布尔删除(对象键){
返回removeNode(hash(key), key, null, false, true) !=null;
}
公共最终Spliteratorspliterator() {
返回新的KeySpliterator(HashMap.this, 0, -1, 0, 0);
}
公共最终无效forEach(消费者?超级Kaction){
节点[]选项卡;
if (action==null) throw new NullPointerException();
if (大小0 (选项卡=表) !=null) {
int mc=modCount;
for (int i=0; i tab.length; ++i) {
for (Nodee=tab[i]; e !=null; e=e.next)
动作.accept(e.key);
}
if (modCount !=mc) 抛出新的ConcurrentModificationException();
}
}
}正如你所看到的,keySet()方法实际上返回了内部final类KeySet的一个实例。我们可以看到KeySet类本身没有任何实例变量。我们来看一下KeySet类定义的size()实例方法。它的实现是直接返回HashMap的实例变量size。还有clear方法,实际上调用的是HashMap对象的clear方法。
keySet方法允许您直接访问Map的键集,而无需复制数据或创建新的数据结构。这通常比将数据复制到新的数据结构更有效。
收藏类
Collections类和Collection接口的区别:Collection是一个接口,而Collections是一个类(可以看做是一个静态方法库)。我们看一下官方文档对Collections的描述:Collections类包含大量用于操作或返回集合的静态方法。它包含用于操作集合的多态算法、用于包装集合的包装方法等等。当集合或类对象为空时,此类中的所有方法都会引发NullPointerException。
OK,关于Java面试热点解析:深入集合框架(第二部分)和的内容到此结束了,希望对大家有所帮助。
【Java面试热点解析:深入集合框架(第二部分)】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
java集合框架面试真的挺重要的!
有13位网友表示赞同!
准备面试的时候一定要好好回顾一下集合框架。
有16位网友表示赞同!
听说这次面试考察深度比较多,不知道有哪些新的问题?
有16位网友表示赞同!
哪家公司面试要求Java集合框架的知识都很全面呢?
有9位网友表示赞同!
希望这篇文章能让我在面试的时候更自信一些。
有16位网友表示赞同!
总结一些常见的集合框架问题,方便以后复习。
有10位网友表示赞同!
我对泛型和迭代器不太了解,这篇文章刚好可以解决我的疑问了。
有6位网友表示赞同!
Java的集合框架真的太强大,学起来有点费劲。
有18位网友表示赞同!
看来面试算法知识还不够,还要加倍学习集合框架啊。
有9位网友表示赞同!
希望能看到一些实际项目中的应用场景,更直观的理解集合框架。
有6位网友表示赞同!
看了标题感觉很有用,收藏起来以后再看一遍。
有18位网友表示赞同!
Java集合框架是面试中常考的点,一定要好好掌握。
有20位网友表示赞同!
这篇文章的文章分类很贴合实际需求,方便找到相关知识点。
有7位网友表示赞同!
准备参加面试试题平台练习的时候,感觉java集合框架很重要。
有14位网友表示赞同!
学习Java集框架对后面的学习也有很大帮助的。
有6位网友表示赞同!
希望能够看到更多关于Java集合框架的面试技巧和经验分享。
有19位网友表示赞同!
看了篇文章后更有信心去面试了!
有12位网友表示赞同!
这篇文章能给我带来新的思路,有助于我更好地理解Java集合框架。
有12位网友表示赞同!
学习新的技术知识总是让人充满兴奋感!
有15位网友表示赞同!
Java确实是一个值得学习的语言!要不断提升自己
有14位网友表示赞同!