List 以特定次序来持有元素,可有重复元素
Set 无法拥有重复元素,内部排序
Map Map中不允许重复的键,value可多值。
HashSet、HashMap、ArrayList、LinkedList、Vector这几个在Java编程中经常用到,他们之间有很多联系,有很多相通的地方、但也有很多不同。首先java集合类主要由两个接口:Collection和Map.Collection又有子接口:Set、Queue、List.(这些基础的接口关系这里不多说了)
HashSet与HashMap,名字很接近,都带有Hash,也就是说他们都依赖Hash算法来存储。我们知道每个对象都有自己的Hash值,这个hash值可以由编程员来编写函数来计算得出,但是要与equal函数相协调(这里涉及到设计类时遵循的原则问题,有兴趣的可以查阅相关资料,hash函数的编写规则)。
那么HashSet与HashMap之间有什么联系呢?HashSet底层使用HashMap来存储的!大家可以看一下jdk的源码,会发现HashSet类源码中有一个HashMap类型的成员变量,其中的成员方法也是调用hashMap的成员方法,只不过存储时,按照key-value对存入HashMap对象中,把值存在key中,Value统一为null。
那么ArrayList与LinkedList有什么联系和区别呢?联系就是他们都实现List接口,因此有许多用法是一样的;区别就要从底层分析了,ArrayList底层使用数组存储,LinkedList底层使用双向链表存储。列表中的每个节点都包含了对前一个和后一个元素的引用。学过数据结构的都知道,数组与链表作为线性表各有优劣,所以ArrayList和LinkedList在效率和使用场景上也有区别。ArrayList在访问数据时效率较高,在插入和删除数据时效率较低。总体上来看ArrayList的效率要略高于LinkedList,因此大多数场景选择Arraylist,除非很多时候要进行插入和删除数据,这时再选择LinkedList。
ArrayList与vector呢?可以说这两个相似度90%,只有一点区别,就是vector是一种线程安全类,它的方法都带有Synchronized关键字。但是vector类很古老,很多方法名都比较长且比较难懂,因此基本不用vector类,但是当遇到多线程情况怎么办呢?不用怕,java提供了Collections工具类,能够将ArrayList转换成线程安全的类!
Queue(队列)类主要实现了一个FIFO(First In First Out,先进先出)的机制。元素在队列的尾部插入(入队操作),并从队列的头部移出(出队操作)。
使用链表来实现队列效果 先进先出
- import java.util.LinkedList;
- public class MainClass {
- public static void main(String[] args) {
- Queue queue = new Queue();
- for (int i = 0; i < 10; i++)
- queue.put(Integer.toString(i));
- while (!queue.isEmpty())
- System.out.println(queue.get());
- }
- }
- class Queue {
- private LinkedList list = new LinkedList();
- public void put(Object v) {
- list.addFirst(v);
- }
- public Object get() {
- return list.removeLast();
- }
- public boolean isEmpty() {
- return list.isEmpty();
- }
- }
-
- import java.util.LinkedList;
- public class MainClass {
- public static void main(String[] args) {
- StackL stack = new StackL();
- for (int i = 0; i < 10; i++)
- stack.push(i);
- System.out.println(stack.top());
- System.out.println(stack.top());
- System.out.println(stack.pop());
- System.out.println(stack.pop());
- System.out.println(stack.pop());
- }
- }
- class StackL {
- private LinkedList list = new LinkedList();
- public void push(Object v) {
- list.addFirst(v);
- }
- public Object top() {
- return list.getFirst();
- }
- public Object pop() {
- return list.removeFirst();
- }
- }
什么是HashSet
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。
public boolean add(Object o)方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true。
什么是HashMap
HashMap实现了Map接口,Map接口对键值对进行映射。Map中不允许重复的键。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。HashMap允许键和值为null。HashMap是非synchronized的。
public Object put(Object Key,Object value)方法用来将元素添加到map中。
那么hashMap的工作原理是什么?
当系统开始初始化HashMap的时候,系统会创建一个长度为capacity的Entry数组。这个数组存储的元素是一个系列元素的索引,也称为“桶”,当一个元素要增加的时候,会计算他的hashcode,然后再数组中寻找他的位置,比如,他的位置有元素占据了,那么会在该元素上,扩展出一条索引链,将数据插入到这个索引链上。
HashSet和HashMap的区别
*HashMap* | |
HashMap实现了Map接口 | |
HashMap储存键值对 | |
使用put()方法将元素放入map中 | |
HashMap中使用键对象来计算hashcode值 | |
HashMap比较快,因为是使用唯一的键来获取对象 | |