常见数据结构有:hashmap、hashtable、 concurrenthashmap。
(相关视频分享:java教学视频)
下面我们分别来进行介绍:
hashmap
底层实现:hashmap底层整体结构是一个数组,数组中的每个元素又是一个链表。每次添加一个对象(put)时会产生一个链表对象(object类型),map中的每个entry就是数组中的一个元素(map.entry就是一个<key,value>),它具有由当前元素指向下一个元素的引用,这就构成了链表。存储原理:当向hsahmap中添加元素的时候,首先计算key对象的hash值,得到数组下标,如果数组该位置为空则插入,否则遍历这个位置链表。当某个节点key对象和node对象均和新元素的equals时,用新元素的value对象替换该节点的value对象,否则插入新节点。(注意:jdk 8之后加入了红黑树)hashmap长度为2的n次幂是为了让length-1的二进制值所有位全为1,这种情况下,hash值与(table.length - 1)进行&运算计算index时,其结果就等同于hashcode后几位的值,此时只要输入的hashcode本身分布均匀,hash算法的结果就是均匀的。所以,hashmap的默认长度为16是为了降低hash碰撞的几率,同时也是一种合适的大小。
hashtable比较点hashmaphashtable
实现原理 见上小节 和hashmap的实现原理几乎一样
key和value 允许key和value为null 不允许key和value为null
扩容策略 2倍扩容oldthr << 1 2倍+1扩容(oldcapacity << 1) + 1
安全性 线程不安全 线程安全
hashtable线程安全的策略实现代价很大,get/put所有相关操作都是synchronized的,在竞争激烈的并发场景中性能非常差。
concurrenthashmapconcurrenthashmap是java并发包中提供的一个线程安全且高效的hashmap实现,它采用了非常精妙的分段锁策略,concurrenthashmap的主干是segment数组。segment继承于reentrantlock,是一种可重入锁。每个segment都是一个子哈希表,segment里维护了一个hashentry数组,并发环境下,对于不同segment的数据进行操作不用考虑锁竞争。
linkedhashmap、treemap、treesetlinkedhashmap:顺序存取的hashmap(基于数组和双向链表实现)。treemap:内部排序(基于红黑树实现)。treeset:有序的set集合(基于二叉树实现)。arraylist、linkedlist、vectorarraylist:动态数组(基于数组实现)。linkedlist:有序数组(基于双向链表实现)。vector:对象容器,可放入不同类的对象(基于数组实现)。collection与collectionscollection:集合类的上级接口,子接口主要有list、set 、queue等。collections:提供对集合进行搜索、排序、替换和线程安全化等操作的工具类。(更多相关面试题推荐:java面试题及答案)
二叉树常见二叉树概念b+树:见数据库部分https://blog.csdn.net/u012102104/article/details/79773362
平衡二叉树(avl树):各个结点左右子树深度差的绝对值不超过1。
哈夫曼树:带权路径长度最小的二叉树称为最优二叉树。哈夫曼树构造不唯一,但所有叶子结点的带权路径长度之和都是最小的。
红黑树:一种自平衡二叉查找树,它的性质有:
节点是红色或黑色。根节点是黑色。每个叶子节点都是黑色的空节点(nil节点)。每个红色节点的两个子节点都是黑色。从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。从每个叶子到根的所有路径上不能有两个连续的红色节点
二叉树的遍历// 1. 先序遍历算法 dlrvoid preorder ( bintree bt ) { if ( bt ) { visit ( bt->data ); preorder ( bt->lchild ); preorder ( bt->rchild ); }}// 2. 中序遍历算法 ldrvoid inorder ( bintree bt ) { if ( bt ) { inorder ( bt->lchild ); visit ( bt->data ); inorder ( bt->rchild ); }}// 3. 后序遍历 lrdvoid postorder ( bintree bt ) { if ( bt ) { postorder ( bt->lchild ); postorder ( bt->rchild ); visit ( bt->data ); }}// 4. 按层次遍历。/* 思路:利用一个队列,首先将根(头指针)入队列,以后若队列不空则取队头元素 p,如果 p 不空,则访问之,然后将其左右子树入队列,如此循环直到队列为空。*/void levelorder ( bintree bt ) { // 队列初始化为空 initqueue ( q ); // 根入队列 enqueue ( q, bt ); // 队列不空则继续遍历 while ( ! queueempty(q) ) { dequeue ( q, p ); if ( p!=null ) { visit ( p->data ); // 左、右子树入队列 enqueue ( q, p->lchild ); enqueue ( q, p->rchild ); } }}// 非递归遍历二叉树一般借助栈实现相关推荐:java入门教程
以上就是java面试——数据结构的详细内容。