java面试题29 牛客 以下关于集合类ArrayList、LinkedList、HashMap描述

java面试题29 牛客 以下关于集合类ArrayList、LinkedList、HashMap描述错误的是()

A HashMap实现Map接口,它允许任何类型的键和值对象,并允许将null用作键或值
B ArrayList和LinkedList均实现了List接口
C 添加和删除元素时,ArrayList的表现更佳
D ArrayList的访问速度比LinkedList快

蒙蔽树上蒙蔽果,蒙蔽树下你和我,我们先看看三者之间的一点使用规则

一、LinkedHashMap

LinkedHashMap会将元素串起来,形成一个双链表结构。可以看到,其结构在HashMap结构上增加了链表结构。数据结构为(数组 + 单链表 + 红黑树 + 双链表),图中的标号是结点插入的顺序


在这里插入图片描述
1. 类的继承关系

public class LinkedHashMap<K,V>  extends HashMap<K,V> implements Map<K,V>

LinkedHashMap继承了HashMap,所以HashMap的一些方法或者属性也会被继承;同时也实现了Map结构(HashMap原理分析

2. 类的属性,相比HashMap新增(由于继承HashMap,所以HashMap中的非private方法和字段,都可以在LinkedHashMap直接中访问)

// 链表头结点
transient LinkedHashMap.Entry<K,V> head;// 链表尾结点
transient LinkedHashMap.Entry<K,V> tail;// 访问顺序(可以指定accessOrder的值,从而控制访问顺序)
final boolean accessOrder;

二、ArrayList

在这里插入图片描述


 

1) 每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量。在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量2)    transient Object[] elementData底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。我们对ArrayList类的实例的所有的操作底层都是基于数组的3)ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的4)java 1.7之前ArrayList默认大小为10,但是1.8之后,默认是空,只有当add第一个元素时,才设置值默认值为105)ArrayList扩容时,正常情况下会扩容1.5倍(newCapacity = oldCapacity + (oldCapacity >> 1),特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值6)indexOf是从头开始查找与指定元素相等的元素,注意,是可以查找null元素的,意味着ArrayList中可以存放null元素的。与此函数对应的lastIndexOf,表示从尾部开始查找7)remove函数用户移除指定下标的元素,此时会把指定下标到数组末尾的元素向前移动一个单位,并且会把数组最后一个元素设置为null,这样是为了方便之后将整个数组不被使用时,会被GC,可以作为小的技巧使用

三、LinkedList

LinkedList底层使用的双向链表结构,有一个头结点和一个尾结点,双向链表意味着我们可以从头开始正向遍历,或者是从尾开始逆向遍历,并且可以针对头部和尾部进行相应的操作
在这里插入图片描述


1. 内部类(内部类Node就是实际的结点,用于存放实际元素的地方)

private static class Node<E> {E item; // 数据域Node<E> next; // 后继Node<E> prev; // 前驱// 构造函数,赋值前驱后继Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}

2. 类的属性

LinkedList的属性非常简单,一个头结点、一个尾结点、一个表示链表中实际元素个数的变量。注意,头结点、尾结点都有transient关键字修饰,这也意味着在序列化时该域是不会序列化的 

3. 注意点

1)add函数用于向LinkedList中添加一个元素,并且添加到链表尾部    

2)在调用remove移除结点时,会调用到unlink函数,将指定的结点从链表中断开

3)LinkedList可以作为双端队列使用,这也是队列结构在Java中一种实现,当需要使用队列结构时,可以考虑LinkedList

四、HashSet和LinkedHashSet

1. HashSet底层是基于HashMap实现的,LinkedHashSet基于LinkedHashMap实现,所以HashSet、LinkedHashSet数据结构就是HashMap或者LinkedHashMap的数据结构

2. HashSet中由于只包含键,不包含值,由于在底层具体实现时,使用的HashMap或者是LinkedHashMap(可以指定构造函数来确定使用哪种结构),我们知道HashMap是键值对存储,所以为了适应HashMap存储,HashSet增加了一个PRESENT类域(类所有),所有的键都有同一个值(PRESENT)

3. add、contains、remove函数都是基于HashMap或者LinkedHashMap做的操作

4. LinkedHashSet继承自HashSet,也实现了一些接口,LinkedHashSet会调用HashSet的父类构造函数,让其底层实现为LinkedHashMap,这样就很好的实现了LinkedHashSet所需要的功能

一、ArrayList 和 LinkedList:

1、区别:

(1)ArrayList是基于动态数组的数据结构,查询快,增删慢,线程不安全。

LinkedList是基于链表的数据结构,查询慢,增删快。线程不安全。

(2)对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。

(3)对ArrayList而言,主要开销是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
(4)在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
(5)LinkedList不支持高效的随机元素访问。
(6)ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。

2、ArrayList和LinkedList的时间复杂度:

(1)ArrayList 是线性表:
get() 直接读取第几个下标,复杂度 O(1);
add(E) 添加元素,直接在后面添加,复杂度O(1);
add(index, E) 添加元素,在第几个元素后面插入,后面的元素需要向后移动,复杂度O(n);
remove()删除元素,后面的元素需要逐个移动,复杂度O(n)。
(2)LinkedList 是链表的操作:
get() 获取第几个元素,依次遍历,复杂度O(n);
add(E) 添加到末尾,复杂度O(1);
add(index, E) 添加第几个元素后,需要先查找到第几个元素,直接指针指向操作,复杂度O(n);
remove()删除元素,直接指针指向操作,复杂度O(1)。

3、ArrayList为什么是线程不安全的?

(1)在 Items[Size] 的位置存放此元素;
(2)增大 Size 的值:
①在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
②而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。 那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。

4、ArrayList能否无限添加元素?会抛异常吗?

使用ArrayList时,可以无限的往里添加元素,因为它底层是由数组实现的,使用无参构造方法时系统会默认提供默认参数10,而使用有参构造函数时我们会指定大小,当我们添加的元素个数大于数组的初始化长度时,ArrayList会自动为其扩容,扩容后的大小是int newCapacity = (oldCapacity * 3)/2 + 1;  (自动增加原来的50%)

HashMap介绍:

(1)HashMap是基于Map接口的非同步实现,结构可以看成数组+链表。

HashMap 是一个散列表,它存储的内容是键值对映射,每一个键值对也叫做Entry(Entry的组成:Key、value、next),key和value都可以为null。HashMap中的映射不是有序的。

(2)HashMap 的实现不是同步的,这意味着它不是线程安全的,后执行的线程会覆盖先执行线程的修改,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法来获取一个线程安全的集合。

Collections.synchronizedMap()实现原理是:Collections定义了一个SynchronizedMap的内部类,这个类实现了Map接口,在调用方法时使用synchronized来保证线程同步,当然了实际上操作的还是我们传入的HashMap实例,简单的说就是Collections.synchronizedMap()方法帮我们在操作HashMap时自动添加了synchronized来实现线程同步。

(3)HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。

        容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量,容量必须是2的N次幂,这是为了提高计算机的执行效率。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 resize 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。(创建新表,将旧表映射到新表中)

        通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 resize 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 resize 操作。

(4)JDK8中HashMap的新特性:如果某个桶中的链表记录过大的话(当前是TREEIFY_THRESHOLD = 8),就会把这个链动态变成红黑二叉树,使查询最差复杂度由O(N)变成了O(logN)。

3、一些有关HashMap的问题:

(1)HashMap的get()、put()方法的工作原理?

        我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存Entry对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。

(2)为什么String, Interger这样的wrapper类适合作为HashMap键?

        因为String是不可变的,也是final的,而且已经重写了equals()和hashCode()方法了。其他的wrapper类也有这个特点。不可变性是必要的,因为为了要计算hashCode(),就要防止键值改变,如果键值在放入时和获取时返回不同的hashcode的话,那么就不能从HashMap中找到你想要的对象。不可变性还有其他的优点如线程安全。如果你可以仅仅通过将某个field声明成final就能保证hashCode是不变的,那么请这么做吧。因为获取对象的时候要用到equals()和hashCode()方法,那么键对象正确的重写这两个方法是非常重要的。如果两个不相等的对象返回不同的hashcode的话,那么碰撞的几率就会小些,这样就能提高HashMap的性能。
正确答案: C

我是歌谣,有什么不合理之处欢迎指出。喜欢敲代码,偶尔刷刷题。

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期科技领域知识)

歌谣带你看java面试题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用python爬取东方财富网机构调研数据

最近有一个需求,需要爬取东方财富网的机构调研数据.数据所在的网页地址为: 机构调研 网页如下所示: 可见数据共有8464页,此处不能直接使用scrapy爬虫进行爬取,因为点击下一页时,浏览器只是发起了javascript网络访问,然后将服务器返回的数据插入网页,无法通过网址直接获取对应页…

spark on yarn webUI logs不能查看

执行spark on yarn 执行&#xff1a;./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster --executor-memory 1G --num-executors 3 ./lib/spark-examples-1.6.3-hadoop2.6.0.jar 10 命令执行成功后在yarn 资源管理界面查看不了logs 参考博…

java面试题30:牛客 下列哪项不属于jdk1.6垃圾收集器?

java面试题30&#xff1a;牛客 下列哪项不属于jdk1.6垃圾收集器&#xff1f; A:Serial收集器 B&#xff1a;parNew收集器 C:CMS收集器 D:G1收集器 1.Serial收集器 单线程收集器&#xff0c;收集时会暂停所有工作线程&#xff08;我们将这件事情称之为Stop The World&…

Silverlight专题(15) - 你自己的视频播放器之自定义MoveToPointSlider

前言&#xff1a; 这几天在网络上看到不少人在问如何创建一个Video Player&#xff08;Silverlight版本&#xff09; 而我在微软和这方面打了不少交道 所以计划用两篇文章解答下大家的问题 本篇文章先介绍下如何创建一个自定义的滚动条 下篇文章创建完整的一个Video Player 问题…

hive 多用户访问模注意问题

首先是安装mysql 安装mysql数据库及客户端 yum install mysql-server yum install mysql servicemysqld start步骤一&#xff1a; yum -y install mysql-server步骤二&#xff1a;service mysqld start步骤三&#xff1a;mysql -u root -p  Enter password: &#xff08;默认…

10行代码实现小程序支付功能!丨实战

前面给大家讲过一个借助小程序云开发实现微信支付的&#xff0c;但是那个操作稍微有点繁琐&#xff0c;并且还会经常出现问题&#xff0c;今天就给大家讲一个简单的&#xff0c;并且借助官方支付api实现小程序支付功能。 传送门&#xff1a;借助小程序云开发实现小程序支付功能…

ASP.NET站点导航(五)

理解并扩展 ASP.NET 2.0 中的站点导航系统 http://msdn.microsoft.com/zh-cn/library/aa479338.aspx 发布日期 : 2006-3-15 | 更新日期 : 2006-3-15David Gristwood Developer & Platform Group, Microsoft 适用于&#xff1a; Microsoft ASP.NET 2.0 (Beta 2) 摘要&#…

java面试题32:Java网络程序设计中,下列正确的描述是()

java面试题32&#xff1a;Java网络程序设计中,下列正确的描述是&#xff08;&#xff09; A&#xff1a;Java网络编程API建立在Socket基础之上 B:Java网络接口只支持tcP以及其上层协议 C&#xff1a;Java网络接口只支持UDP以及其上层协议 D:Java网络接口支持IP以上的所有高…

【收藏】C# WinForm开发系列 - DataGridView 使用方法集锦 - 宁波.Net技术讨论区

1.DataGridView实现课程表 testcontrol.rar 2.DataGridView二维表头及单元格合并 DataGridView单元格合并和二维表头.rar myMultiColHeaderDgv.rar 3.DataGridView单元格显示GIF图片 gifanimationindatagrid.rar 4.自定义显示DataGridView列(行头显示行号与图标,同一单元格显示…

Java中Map, List, Set和Queue的区别和使用场景

转&#xff1a;https://blog.csdn.net/kingcat666/article/details/75579632 1. Java集合类基本概念 在编程中&#xff0c;常常需要集中存放多个数据。从传统意义上讲&#xff0c;数组是我们的一个很好的选择&#xff0c;前提是我们事先已经明确知道我们将要保存的对象的数量…

Proxy server 緩存 jsp html

如果服務器端使用Proxy server,jsp頁面會出現頁面混亂的問題.(不同用戶登陸,出現的是同一個用戶的資料),為了避免這種情況存在,可以有兩種方法解決. eg: menu 所在頁面為toppanel.jsp,鏈接就為:http://localhost:8080/q/toppanel.jsp. 這樣user登陸可能會出現manager的menu,man…

shiro学习(6):shiro连接数据库

首先我们先看一下数据库 再看看数据库的测试数据 在我们创建好的maven项目中看一下目录结构 在pom.xml引入 <dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency&g…

【js监听报错】页面监听js报错问题

<html> <head> <script type"text/javascript">// 页面监听js报错问题 οnerrοrhandleErrvar txt"" function handleErr(msg,url,l) { txt"本页中存在错误如下&#xff1a;\n\n" txt"错误&#xff1a;" msg &quo…

链表逆序(JAVA实现)

题目&#xff1a;将一个有链表头的单向单链表逆序 分析&#xff1a; 链表为空或只有一个元素直接返回&#xff1b;设置两个前后相邻的指针p,q&#xff0c;使得p指向的节点为q指向的节点的后继&#xff1b;重复步骤2&#xff0c;直到q为空&#xff1b;调整链表头和链表尾&…

【微信网页直接下载app】微信跳转-微信浏览器中直接唤起本地浏览器和App

文档传送门&#xff1a;https://github.com/EthanOrange/wechat-redirectdemo&#xff1a; http://wxredirect.jslab.fun/call-app 转载于:https://www.cnblogs.com/xiaohuizhang/p/11377553.html

单例模式的八种写法比较

转:https://www.cnblogs.com/zhaoyan001/p/6365064.html 单例模式是最常用到的设计模式之一&#xff0c;熟悉设计模式的朋友对单例模式都不会陌生。一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式。但是除了这两种方式&#xff0c;本文还会介绍其他几种实现…

java面试题37 关于对象成员占用内存的说法哪个正确?( )

java面试题37 关于对象成员占用内存的说法哪个正确&#xff1f;&#xff08; &#xff09; A 同一个类的对象共用同一段内存 B 同一个类的对象使用不同的内存段&#xff0c;但静态成员共享相同的内存空间 C 对象的方法不占用内存 D 以上都不对 蒙蔽树上蒙蔽果&#xff0c;…

.NET Framework学习笔记(十)

17.委托 .NET框架使用委托delegate来提供回调函数机制。 classSet{ private Object[] items; public Set(int numItems) { items new Object[numItems]; for (int i 0; i < numItems; i) { items[i] i; } }publicdel…

GridView强制不换行

前提是不能设置GridView的列宽(可以设置表头的宽度代替列宽) 把下面代码加到Me.objGv.DataBind()下面 GridView表头强制不换行objGv.HeaderRow.Style.Add("word-break", "keep-all")GridView内容强制不换行Fori AsInteger0ToobjGv.Rows.Count -1Forj AsInt…

Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较

转发:https://www.cnblogs.com/zx-bob-123/archive/2017/12/26/8118074.html 0. 前言 HashMap和HashTable的区别一种比较简单的回答是&#xff1a; &#xff08;1&#xff09;HashMap是非线程安全的&#xff0c;HashTable是线程安全的。 &#xff08;2&#xff09;HashMap的…