`
BS_YG
  • 浏览: 33209 次
社区版块
存档分类
最新评论

ArrayList、LinkedList、Vector、HashSet、Treeset、HashMap、TreeMap的区别和适用场景

阅读更多

ArrayListLinkedList的区别和适用场景

Arraylist

优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。

缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。   

LinkedList

优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作addremoveLinedList比较占优势

缺点:因为LinkedList要移动指针,所以查询操作性能比较低。

适用场景分析:

 

当需要对数据进行对此访问的情况下选用ArrayList,当需要对数据进行多次增加删除修改时采用LinkedList

 

ArrayListVector的区别和适用场景

ArrayList有三个构造方法:

 

public ArrayList(int initialCapacity)//构造一个具有指定初始容量的空列表。  
public ArrayList()//构造一个初始容量为10的空列表。  
public ArrayList(Collection<? extends E> c)//构造一个包含指定 collection 的元素的列表 

 Vector有四个构造方法:

 

public Vector()//使用指定的初始容量和等于零的容量增量构造一个空向量。  
public Vector(int initialCapacity)//构造一个空向量,使其内部数据数组的大小,其标准容量增量为零。  
public Vector(Collection<? extends E> c)//构造一个包含指定 collection 中的元素的向量  
public Vector(int initialCapacity,int capacityIncrement)//使用指定的初始容量和容量增量构造一个空的向量  

ArrayListVector都是用数组实现的,主要有这么三个区别:

 

 

1.Vector是多线程安全的,而ArrayList不是,这个可以从源码中看出,Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;

 

2.两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同。

 

3.Vector可以设置增长因子,而ArrayList不可以。

 

适用场景分析:

1.Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。
2.
如果集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有一定的优势。

HashSetTreeset的适用场景

1.TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null 

2.HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束 

3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例

 

 

   适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet

 

HashMapTreeMap的适用场景

 

HashMap 非线程安全  

HashMap基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()equals()[可以重写hashCode()equals()],为了优化HashMap空间的使用,您可以调优初始容量和负载因子。 

 

(1)HashMap(): 构建一个空的哈希映像 
(2)HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射 

(3)HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像 

(4)HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像 

TreeMap
非线程安全基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。 

(1)TreeMap():构建一个空的映像树 
(2)TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素 

(3)TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序 

(4)TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序 

适用场景分析:

 

HashMap适用于在Map中插入、删除和定位元素。 
Treemap适用于按自然顺序或自定义顺序遍历键(key) 

测试代码如下(部分代码来源于teye博客及论坛)

 

 
import java.util.HashMap; 
import java.util.Hashtable; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.TreeMap; 
public class HashMaps { 
public static void main(String[] args) { 
Map<String, String> map = new HashMap<String, String>(); 
map.put("a", "aaa"); 
map.put("b", "bbb"); 
map.put("c", "ccc"); 
map.put("d", "ddd"); 
Iterator<String> iterator = map.keySet().iterator(); 
while (iterator.hasNext()) { 
Object key = iterator.next(); 
System.out.println("map.get(key) is :" + map.get(key)); 
} 
// 定义HashTable,用来测试 
Hashtable<String, String> tab = new Hashtable<String, String>(); 
tab.put("a", "aaa"); 
tab.put("b", "bbb"); 
tab.put("c", "ccc"); 
tab.put("d", "ddd"); 
Iterator<String> iterator_1 = tab.keySet().iterator(); 
while (iterator_1.hasNext()) { 
Object key = iterator_1.next(); 
System.out.println("tab.get(key) is :" + tab.get(key)); 
} 
TreeMap<String, String> tmp = new TreeMap<String, String>(); 
tmp.put("a", "aaa"); 
tmp.put("b", "bbb"); 
tmp.put("c", "ccc"); 
tmp.put("d", "cdc"); 
Iterator<String> iterator_2 = tmp.keySet().iterator(); 
while (iterator_2.hasNext()) { 
Object key = iterator_2.next(); 
System.out.println("tmp.get(key) is :" + tmp.get(key)); 
} 
} 
} 

 运行结果如下: 

 

map.get(key) is :ddd 
map.get(key) is :bbb 
map.get(key) is :ccc 
map.get(key) is :aaa 
tab.get(key) is :bbb 
tab.get(key) is :aaa 
tab.get(key) is :ddd 
tab.get(key) is :ccc 
tmp.get(key) is :aaa 
tmp.get(key) is :bbb 
tmp.get(key) is :ccc 
tmp.get(key) is :cdc 
HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。 
下面就要进入本文的主题了。先举个例子说明一下怎样使用HashMap

 

 
import java.util.*; 
public class Exp1 { 
public static void main(String[] args){ 
HashMap h1=new HashMap(); 
Random r1=new Random(); 
for (int i=0;i<1000;i++){ 
Integer t=new Integer(r1.nextInt(20)); 
if (h1.containsKey(t)) 
((Ctime)h1.get(t)).count++; 
else 
h1.put(t, new Ctime()); 
} 
System.out.println(h1); 
} 
} 
class Ctime{ 
int count=1; 
public String toString(){ 
return Integer.toString(count); 
} 
} 

 在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。 

 

前面介绍了,HashMap是基于HashCode的,在所有对象的超类Object中有一个HashCode()方法,但是它和equals方法一样,并不能适用于所有的情况,这样我们就需要重写自己的HashCode()方法。下面就举这样一个例子: 

 

 
import java.util.*; 
public class Exp2 { 
public static void main(String[] args){ 
HashMap h2=new HashMap(); 
for (int i=0;i<10;i++) 
h2.put(new Element(i), new Figureout()); 
System.out.println("h2:"); 
System.out.println("Get the result for Element:"); 
Element test=new Element(5); 
if (h2.containsKey(test)) 
System.out.println((Figureout)h2.get(test)); 
else 
System.out.println("Not found"); 
} 
} 
class Element{ 
int number; 
public Element(int n){ 
number=n; 
} 
} 
class Figureout{ 
Random r=new Random(); 
boolean possible=r.nextDouble()>0.5; 
public String toString(){ 
if (possible) 
return "OK!"; 
else 
return "Impossible!"; 
} 
} 

 在这个例子中,Element用来索引对象Figureout,也即Element为key,Figureout为value。在Figureout中随机生成一个浮点数,如果它比0.5大,打印"OK!",否则打印"Impossible!"。之后查看Element(3)对应的Figureout结果如何。 

 


结果却发现,无论你运行多少次,得到的结果都是"Not found"。也就是说索引Element(3)并不在HashMap中。这怎么可能呢? 
原因得慢慢来说:Element的HashCode方法继承自Object,而Object中的HashCode方法返回的HashCode对应于当前的地址,也就是说对于不同的对象,即使它们的内容完全相同,用HashCode()返回的值也会不同。这样实际上违背了我们的意图。因为我们在使用 HashMap时,希望利用相同内容的对象索引得到相同的目标对象,这就需要HashCode()在此时能够返回相同的值。在上面的例子中,我们期望 new Element(i) (i=5)与 Elementtest=newElement(5)是相同的,而实际上这是两个不同的对象,尽管它们的内容相同,但它们在内存中的地址不同。因此很自然的,上面的程序得不到我们设想的结果。下面对Element类更改如下:

 

 
class Element{ 
int number; 
public Element(int n){ 
number=n; 
} 
public int hashCode(){ 
return number; 
} 
public boolean equals(Object o){ 
return (o instanceof Element) && (number==((Element)o).number); 
} 
} 

 在这里Element覆盖了Object中的hashCode()和equals()方法。覆盖hashCode()使其以number的值作为 hashcode返回,这样对于相同内容的对象来说它们的hashcode也就相同了。而覆盖equals()是为了在HashMap判断两个key是否相等时使结果有意义修改后的程序运行结果如下: 

 

h2: 
Get the result for Element: 
Impossible! 
请记住:如果你想有效的使用HashMap,你就必须重写在其的HashCode()。 
还有两条重写HashCode()的原则: 
[list=1] 
不必对每个不同的对象都产生一个唯一的hashcode,只要你的HashCode方法使get()能够得到put()放进去的内容就可以了。即"不为一原则"。 

生成hashcode的算法尽量使hashcode的值分散一些,不要很多hashcode都集中在一个范围内,这样有利于提高HashMap的性能。即"分散原则"。至于第二条原则的具体原因,有兴趣者可以参考Bruce Eckel的《Thinking in Java》,在那里有对HashMap内部实现原理的介绍,这里就不赘述了。 
掌握了这两条原则,你就能够用好HashMap编写自己的程序了。不知道大家注意没有,java.lang.Object中提供的三个方法:clone(),equals()和hashCode()虽然很典型,但在很多情况下都不能够适用,它们只是简单的由对象的地址得出结果。这就需要我们在自己的程序中重写它们,其实java类库中也重写了千千万万个这样的方法。利用面向对象的多态性——覆盖,Java的设计者很优雅的构建了Java的结构,也更加体现了Java是一门纯OOP语言的特性。

细节注意:

时间测试方法:System.currentTimeMillis()

遍历方法:Iterator迭代器

超级for

TreeSet xx = new TreeSet();

         for(Object obj:xx){

         System.out.println(obj);

         }

 

 

Java中的泛型:泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。

Java 泛型的参数只可以代表类,不能代表个别对象。由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。

 

 

 

 

分享到:
评论

相关推荐

    第8讲 对比Vector、ArrayList、LinkedList有何区别1

    在Java集合框架的学习中,除了List接口的实现,还应了解Set接口(如HashSet和TreeSet)和Map接口(如HashMap和TreeMap)等其他容器,以及它们的数据结构和操作特性。同时,关注集合框架的并发支持,如...

    JAVA容器讲解.pdf

    Java容器讲解PPT,Collection Map(HashMap TreeMap LinkedHashMap) List (ArrayList LinkedList Vector) Set (HashSet TreeSet LinkedHashSet)

    Java集合讲义大全.docx

    常见的 List 实现类有 ArrayList 和 LinkedList。 * Set 是一个无序集合,不允许存储重复的数据。常见的 Set 实现类有 HashSet 和 TreeSet。 * Map 是一个无序集合,集合中包含一个键对象和一个值对象,键对象不允许...

    第一行代码Java源代码第13章课程代码Java类集框

    类集框架是Java标准库的一部分,提供了用于存储和操作对象的数据结构,如ArrayList、LinkedList、HashSet、HashMap等。这些数据结构在实际编程中广泛应用,理解和熟练使用它们是提升编程效率的关键。 在Java中,类...

    java集合总结副本共19页.pdf.zip

    Java集合框架是Java编程语言中...这个“java集合总结副本共19页.pdf.zip”压缩包很可能是对Java集合框架的详细讲解,涵盖了重要的知识点,包括ArrayList、LinkedList、HashSet、HashMap、TreeSet、TreeMap等主要集合类...

    我的面试问题总结.docx

    实现类如ArrayList、LinkedList、HashSet、HashMap等,它们实现了这些接口并提供了具体的实现。例如,ArrayList和LinkedList都是List接口的实现,但它们在内部结构和性能上有显著差异。 二、Set、Map、List三者对比...

    初级JAVA PPT教程,适用于初级学者。忘珍惜

    本篇PPT教程针对初级学者,将介绍一些核心的Java类,如Date、Calendar、Math以及BigInteger,还会涉及常用的容器类,包括ArrayList、LinkedList、HashSet、HashMap、TreeSet和TreeMap。 首先,我们来看Date类。Date...

    细说Java之常用集合类.rar

    Java是一种广泛使用的面向对象的编程语言,其丰富的库和强大的集合框架是其核心特性之一。...深入理解ArrayList、LinkedList、HashSet、HashMap等集合类的特性和应用场景,将使你在编程实践中更加游刃有余。

    集合框架的各自区别.pdf

    Java集合框架是编程中不可或缺的一部分,它提供了多种数据结构和算法,使得存储、...在特定场景下,LinkedList、TreeSet和TreeMap也能发挥其独特优势。了解这些集合的区别和特点,有助于选择最适合特定需求的集合类型。

    java方向各阶段重点知识点 .docx

    主要分为两大类:接口(如List、Set、Queue)和实现类(如ArrayList、LinkedList、HashSet、HashMap等)。 1. **ArrayList和LinkedList**:这两个都是List接口的实现类,主要区别在于数据结构和性能。ArrayList基于...

    Java集合 练习代码

    本练习代码主要围绕Java集合框架展开,包括ArrayList、LinkedList、HashSet、HashMap等各种类型的集合以及它们的使用方法。通过这些代码示例,我们可以深入理解Java集合的各种特性和操作。 首先,我们来探讨...

    中山大学研究生学院java讲义之(对象容器)

    对象容器通常指的是Java集合框架的一部分,包括ArrayList、LinkedList、HashSet、HashMap等类,它们为对象提供了存储、查找和操作的机制。 首先,我们来看ArrayList。ArrayList是一个基于数组实现的动态列表,可以...

    Java容器类的教学实践与思考.pdf

    对于TreeSet和TreeMap,可以通过比较它们与ArrayList和HashMap的异同,解释它们的排序机制和适用情况。 以TreeSet为例,教学时可以首先解释其内部的红黑树结构,然后通过实例演示添加元素、查找元素、排序等操作,...

    Collections源码java-Java_collections:Java的ArrayList、LinkedList、HashMap、Tr

    Collections 源码 java Java Java的ArrayList、LinkedList、HashMap、TreeMap、LinkedHashMap、HashSet、TreeSet相关源码分析,及相关问题和应用总结。

    java常用集合

    本文将深入探讨Java中的常用集合类,包括ArrayList、LinkedList、HashSet、HashMap等,以及它们的特点和使用场景。 首先,我们来看ArrayList。ArrayList是基于数组实现的集合,它提供了动态数组的功能,允许在列表...

    java中ArrayList 、LinkList区别.doc

    在Java编程语言中,ArrayList和LinkedList都是集合框架中两种重要的数据结构,它们...在实际开发中,还可以结合ArrayList和LinkedList的特性,利用Java集合框架中的其他数据结构,如HashSet或HashMap,来优化代码性能。

    java集合类类性能测试源代码

    - TreeSet虽然有序,但插入和查找可能比HashSet慢,因为涉及到排序操作。 7. **HashMap vs TreeMap性能测试** - TreeMap保持了键的排序,但插入和查找速度通常比HashMap慢。 性能测试通常会包含以下几个方面: -...

    大公司最喜欢问的Java集合类面试题.zip

    这个文档“大公司最喜欢问的Java集合类面试题”可能包含了对这一主题的深入探讨,包括ArrayList、LinkedList、HashSet、HashMap等常见集合类,以及它们的底层实现、性能特征、操作复杂度等方面的问题。 1. **...

    应聘Java笔试时可能出现问题

    本文将深入探讨Java基础、集合框架以及常见数据结构如ArrayList、Vector、HashMap和Hashtable之间的区别。 1. **Java访问修饰符**:在Java中,`public`、`private`、`protected`以及默认(无修饰符)定义了类成员的...

    02-Java集合容器面试题-重点.docx

    Java集合容器概述、集合框架、List、Set、Map接口、Iterator、ArrayList、LinkedList、Vector、HashSet、HashMap、Queue、BlockingQueue、ConcurrentHashMap等。 Java 集合容器概述 Java 集合容器是用于存储数据...

Global site tag (gtag.js) - Google Analytics