java集合
最近面试总是被问到collection和Map的问题,于是总结下来,打通这一环。
实现collection的,常用的无非就那么三个,queue、set、list、deque(这个是为了好玩写上来的,是双端队列,double ended queue的缩写)。
实现map的呢,常见的也是三个,hashmap、treemap、hashtable等。
一说到都有hashtable,大家知道,翻译过来,就是hash表(其实我是看了一篇博客才反应过来,得知,在java中,因为hashtable是同步的,不怎么常用,所以就有hashmap这个猴子当大王了)。不管怎么说,这个hash表是一定要说的。
1.什么是哈希表?
哈希表是一种数据结构,它提供了快速的插入操作和查找操作。其基于数组来实现。
2.哈希化
1)直接将关键字作为索引。
2)将单词转换成索引。
<1>将字母转换成ASCII码,然后进行相加
<2>幂的连乘
<3>压缩可选值
3.压缩后仍然可能出现的问题。
冲突:不能保证每个单词都映射到数组的空白单元。
解决办法:
<1>开放地址法
<2>链地址法
哈希表是一种重要的存储方式,也是一种常见的检索方法。其基本思想是将关系码的值作为自变量,通过一定的函数关系计算出对应的函数值,把这个数值解释为结点的存储地址,将结点存入计算得到存储地址所对应的存储单元。检索时采用检索关键码的方法。现在哈希表有一套完整的算法来进行插入、删除和解决冲突。在Java中哈希表用于存储对象,实现快速检索。
Java.util.Hashtable提供了种方法让用户使用哈希表,而不需要考虑其哈希表真正如何工作。
哈希表类中提供了三种构造方法,分别是:
public Hashtable()
public Hashtable(int initialcapacity)
public Hashtable(int initialCapacity,float loadFactor)
参数initialCapacity是Hashtable的初始容量,它的值应大于0。loadFactor又称装载因子,是一个0.0到0.1之间的float型的浮点数。它是一个百分比,表明了哈希表何时需要扩充,例如,有一哈希表,容量为100,而装载因子为0.9,那么当哈希表90%的容量已被使用时,此哈希表会自动扩充成一个更大的哈希表。如果用户不赋这些参数,系统会自动进行处理,而不需要用户操心。
Hashtable提供了基本的插入、检索等方法。
碰到哪儿,写到哪儿。
《list》
今天碰到的是List,叫列表,这也是一种抽象数据类型,其底层当然还是数组。
它的实现类有两个,linkedlist和arraylist。
顾名思义,linkedlist,就是用链表来实现的,特点是,查询慢,但增删块,这也正是链表的特点,
arraylist,自然就是用数组来实现的。特点是,查询很快,但增删很慢,因为删一个元素后要挪动后续所有元素的位置。线程不同步。
Vector,也是数组来实现的,跟arraylist唯一的区别就是它是线程同步的。
public ArrayList() { this(10); } public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); this.elementData = new Object[initialCapacity]; }
private transient Entry<E> header = new Entry<E>(null, null, null); private transient int size = 0; /** * Constructs an empty list. */ public LinkedList() { header.next = header.previous = header; }
但不管怎么说,list,列表,这种数据类型,它存放的数据都是有序的。而且,元素可以重复。
好,写到这儿,就不得不说一下,同为collection下的set接口。
这是一个不含有重复元素的集合。
哼,不看源码不知道,一看我保证你会吓一跳。所谓的set,其实是用map来做的。哈哈哈哈。
看,这就是HashSet的构造函数。
public HashSet() { map = new HashMap<E,Object>(); }
想知道TreeSet的构造函数吗?嘿嘿
public TreeSet() { this(new TreeMap<E,Object>()); }
看,一个hashmap,一个treemap,我从未见过如此无耻之代码。给你来回套着玩。
但为什么会这样呢?
为什么set分明是实现的collection接口,但用的却全是map家族下的数据类型呢?
不看别人的博客不知道,一看才恍然大明白。
原来,set集合,其实可以看成是map集合中的所有的key的集合。诸不知,map有一个方法叫做,keyset,这个名字,就透露出了,set其实就相当于map的key的集合。
而这,也符合set的特点,不可重复,无序。但它又要符合集合的特点,比如添加功能啦,删除功能啦,等等。
但问题又来了,它再往下的本质又是什么呢?是数组?还是链表。首先,可以肯定的是,这个无序,那也就是说,跟数组和链表没有关系了。所以,一定存在另一种数据结构,实现这种不可重复和无序的需求。
posted on 2016-07-01 16:12 LinKing1993 阅读(167) 评论(0) 收藏 举报
浙公网安备 33010602011771号