HashSet、HashMap、ArrayList、LinkedList、Vector区别

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,先进先出)的机制。元素在队列的尾部插入(入队操作),并从队列的头部移出(出队操作)。

使用链表来实现队列效果 先进先出

  1. import java.util.LinkedList;  
  2. public class MainClass {  
  3.   public static void main(String[] args) {  
  4.     Queue queue = new Queue();  
  5.     for (int i = 0; i < 10; i++)  
  6.       queue.put(Integer.toString(i));  
  7.     while (!queue.isEmpty())  
  8.       System.out.println(queue.get());  
  9.   }  
  10. }  
  11. class Queue {  
  12.   private LinkedList list = new LinkedList();  
  13.   public void put(Object v) {  
  14.     list.addFirst(v);  
  15.   }  
  16.   public Object get() {  
  17.     return list.removeLast();  
  18.   }  
  19.   public boolean isEmpty() {  
  20.     return list.isEmpty();  
  21.   }  
  22. }  

使用链表实现栈效果  先进后出

  1. import java.util.LinkedList;  
  2. public class MainClass {  
  3.   public static void main(String[] args) {  
  4.     StackL stack = new StackL();  
  5.     for (int i = 0; i < 10; i++)  
  6.       stack.push(i);  
  7.     System.out.println(stack.top());  
  8.     System.out.println(stack.top());  
  9.     System.out.println(stack.pop());  
  10.     System.out.println(stack.pop());  
  11.     System.out.println(stack.pop());  
  12.   }  
  13. }  
  14. class StackL {  
  15.   private LinkedList list = new LinkedList();  
  16.   public void push(Object v) {  
  17.     list.addFirst(v);  
  18.   }  
  19.   public Object top() {  
  20.     return list.getFirst();  
  21.   }  
  22.   public Object pop() {  
  23.     return list.removeFirst();  
  24.   }  
  25. }  



什么是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*    *HashSet*
HashMap实现了Map接口    HashSet实现了Set接口
HashMap储存键值对    HashSet仅仅存储对象
使用put()方法将元素放入map中    使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值    HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false
HashMap比较快,因为是使用唯一的键来获取对象    HashSet与Hashmap 存取速度基本一致,HashSet把HashMap进行了封装

你可能感兴趣的:(java)