Java基础——集合框架
Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。Java平台的完整集合框架如下图所示:
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
发现一个特点,上述所有的集合Collection类,都实现了Iterator接口,(Map中并没有实现这个接口),这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口ListIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。
- 如果是Iterator接口,那么在遍历集合中元素的时候,只能单向遍历,只能通过next()访问下一个元素,依次往后遍历,被遍历后的元素不会在遍历到。所有集合均实现了这个接口,比如HashSet,HashMap;
- 而如果是ListIterator接口,那么在遍历集合中元素的时候,可以实现双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,更加灵活。但是只有List的子类才实现了这个接口,比如ArrayList。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
将一些抽象类去掉之后的简化版如下图所示。

下面简单介绍下每一种集合类型的特点:
- Collection:每个“槽”只有一个元素
- Set:每个元素必须是唯一的,不能含有重复的元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。不保证维护元素的顺序。
- HashSet***:主要的特点是:存入HashSet的元素必须定义hashCode()方法,采用散列的存储方法,所以没有顺序。这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致。底层的物理结构是哈希表。
- LinkedHashSet*:主要特点是:具有HashSet的查询速度,且背部使用链表维护元素的顺序(插入的次序),存入LinkedHashSet的元素必须定义hashCode()方法,底层的物理结构是链表结合哈希表。
- TreeSet*:主要特点是是:保持次序的Set,存入TreeSet的元素必须实现Comparable接口,在加入元素时会自动进行排序。底层的物理结构是红黑树。
- HashSet***:主要的特点是:存入HashSet的元素必须定义hashCode()方法,采用散列的存储方法,所以没有顺序。这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致。底层的物理结构是哈希表。
- List:将以特定次序存储元素,可以重复。
- ArrayList***:主要特点是:长于随机访问元素,但是在List中间插入和移除元素时较慢,加入元素的顺序就是其存放元素的顺序。底层的物理结构是数组。
- LinkedList***:只要特点是:随机访问速度较慢,可以在任何位置进行高效地插入和删除操作的有序序列。底层的物理结构是双向链表。LinkedList具有直接实现Stack(栈)的所有功能的方法,因此可以直接将LinkedList作为Stack使用。LinkedList也实现很多方法支持Quene(队列)的行为,并且其也实现了Quene接口,因此LinkedList也可以用作Quene的一种实现,可以将LinkedList向上转型为Quene。
- Vector:主要特点是:和ArrayList功能和特点基本类似,不同的地方在于Vector是线程安全的,所以速度相对慢一些。底层的物理结构也是数组。现在基本上不怎么用了
- Stack:现在不用了,可以用LinkedList来当做Stack.
- Quene:先进先出的容器。从容器的一端放入事物,从另一端取出。一般用LinkedList来当做Quene.
- Set:每个元素必须是唯一的,不能含有重复的元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。不保证维护元素的顺序。
- Map:每个“槽”中存放的是键值对(key-value),可以使用键来查找值。
- HashMap***:主要特点是:基于散列表的实现(取代了Hashtable)。插入和查询键值对的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器性能。
- LinkedHashMap*:类似于HashMap,但是迭代遍历时,取得的键值对的顺序是其插入的次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点,而在迭代访问时更快,因为其用链表维护内部次序,
- TreeMap**:基于红黑树的实现。加入TreeMap的元素会被自动排序,排序次序有Comparable或Comparator决定( Comparable和Comparator的区别)。是唯一带有subMap()方法的Map,可以返回一个子树。
- Hashtable:线程安全的,同HashMap。现在基本上不用了
- WeakedHashMap:弱键(weak key)映射,允许释放映射所指向的对象
- IdentifyHashMap:使用==代替equals()对“键”进行比较的散列映射。
- HashMap***:主要特点是:基于散列表的实现(取代了Hashtable)。插入和查询键值对的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器性能。
代码实例:HashSetDemo
package edu.sjtu.erplab.collection; import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class HashSetDemo { public static void main(String[] args) {
Set<String> set=new HashSet<String>(); set.add("a");
set.add("b");
set.add("c");
set.add("c");
set.add("d"); //使用Iterator输出集合
Iterator<String> iter=set.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:set)
{
System.out.print(e+" ");
}
System.out.println(); //使用toString输出集合
System.out.println(set);
}
}
代码实例:TreeSet
代码实例:ArrayListDemo
package edu.sjtu.erplab.collection; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class ArrayListDemo {
public static void main(String[] args) {
List<String> arrList=new ArrayList<String>(); arrList.add("a");
arrList.add("b");
arrList.add("c");
arrList.add("c");
arrList.add("d"); //使用Iterator输出集合
Iterator<String> iter=arrList.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:arrList)
{
System.out.print(e+" ");
}
System.out.println(); //使用toString输出集合
System.out.println(arrList);
}
}
代码实例:LinkedListTest
package edu.sjtu.erplab.collection; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class LinkedListTest { public static void main(String[] args) { List<String> a=new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
System.out.println(a); List<String> b=new ArrayList<String>();
b.add("d");
b.add("e");
b.add("f");
b.add("g");
System.out.println(b); //ListIterator在Iterator基础上添加了add(),previous()和hasPrevious()方法
ListIterator<String> aIter=a.listIterator();
//普通的Iterator只有三个方法,hasNext(),next()和remove()
Iterator<String> bIter=b.iterator(); //b归并入a当中,间隔交叉得插入b中的元素
while(bIter.hasNext())
{
if(aIter.hasNext())
aIter.next();
aIter.add(bIter.next());
}
System.out.println(a); //在b中每隔两个元素删除一个
bIter=b.iterator(); while(bIter.hasNext())
{
bIter.next();
if(bIter.hasNext())
{
bIter.next();//remove跟next是成对出现的,remove总是删除前序
bIter.remove();
}
}
System.out.println(b); //删除a中所有的b中的元素
a.removeAll(b);
System.out.println(a);
}
}
最后,看到了一些关于集合架构源码剖析的文章,有兴趣可以看一下,多了解内部原理也是挺好的。
各大类直接的区别可以参见:java中Map,List与Set的区别
Java集合框架源码剖析:HashSet 和 HashMap:
http://blog.jobbole.com/101493/
java中的HashTable,HashMap和HashSet
注意:HashMap的初始化容量为16,负载因子为0.75,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大两倍。
HashSet的内部结构就是HashMap,只是每个键值对的值都确定为一个常量对象PRESENT(private static final Object PRESENT = new Object();)
Java集合框架源码剖析:LinkedHashSet 和 LinkedHashMap:
http://blog.jobbole.com/101724/
注意:LinkedHashSet 和 LinkedHashMap之间的关系和HashSet与HashMap之间的关系是一样的。只是在其中加入了双向链表的结构。插入的时候依然按照HashMap的方式插入,只是在元素之间用双向链表表示前后的顺序,所以查找和插入都很快速。
Java集合框架源码剖析:TreeSet 和 TreeMap:
http://blog.jobbole.com/102230/
注意:TreeSet 和 TreeMap之间的关系和HashSet与HashMap之间的关系是一样的。TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。TreeMap底层通过红黑树(Red-Black tree)实现,也就意着containsKey(), get(), put(), remove()都有着log(n)的时间复杂度。
红黑树的原理:
http://blog.jobbole.com/103045/
《Thinking In Algorithm》07.Red-Black Trees(红黑树)
Java集合框架源码剖析:ArrayList:
http://blog.jobbole.com/101796/
注意:ArrayList的初始化容量为10,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大原先的1.5倍,eg:第一次扩容至10+10/2=15,第二次是15+15/2 = 22,以此类推。
Java集合框架源码剖析:LinkedList:
http://blog.jobbole.com/101830/
注意:LinkedList中定义的双向链表的Node节点如下:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
Java基础——集合框架的更多相关文章
- 十五、Java基础---------集合框架体系以及List
在介绍集合之前先说一下数组,正如我们所知,数组是某一类型数据的集合,强调的是数据,而且必须单一:集合框架的不同之处在于存储的数据类型没有任何限制,既可以存储基本数据类型(会自动提升为相应的包装类)也可 ...
- java基础--集合框架的认识
一.集合框架 对于不知道存储数量和更复杂的方式存储对象用集合框架. 其中有几个常用的接口和实现类:Collection父接口.List接口,Set接口,Map接口, ArrayList实现类.Link ...
- 十七、Java基础---------集合框架之Map
前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...
- Java基础——集合框架(待整理)
ArrayList 和 和 Vector 的区别 从代码的最终的操作形式上可以发现,代码的输出结果与之前是一样的,而且没有区别,但是两者的区别还在于其内部的组成上. No. 区别点 Vector Ve ...
- 十六、Java基础---------集合框架之Set
写在前面的话,这篇文章在昨天就写好了,今天打开的时候一不小心将第二天的文章粘贴到了这篇文章,很不幸的是除了标题之外依然面目全非,今天带着沉痛的心情再来写这篇文章! 上篇文章介绍了Collection体 ...
- Java基础---集合框架---迭代器、ListIterator、Vector中枚举、LinkedList、ArrayList、HashSet、TreeSet、二叉树、Comparator
为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储对 ...
- Java 基础 集合框架
Java中的集合从类的继承和接口的实现结构来说,可以分为两大类: 1 继承自Collection接口,包含List.Set和Queue等接口和实现类. 2 继承自Map接口,主要包含哈希表相关的集合类 ...
- Java基础-集合框架-ArrayList源码分析
一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...
- Java基础-集合框架的学习大纲
1.List 和 Set 的区别 2.HashSet 是如何保证不重复的 3.HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)? 4.HashMap 的扩容过程 ...
随机推荐
- 如何巧用.htaccess设置网站的压缩与缓存
<IfModule mod_expires.c> ExpiresActive On ExpiresDefault A86400 ExpiresByType image/gif A25920 ...
- Shell 重定向 &>file,2>&1,1>&2 的区别
Shell上:0表示标准输入1表示标准输出2表示标准错误输出> 默认为标准输出重定向,与1>相同2>&1 意思是 把标准错误输出重定向到标准输出1>&2 意思是 ...
- linuc c 代码示例
fork的应用: #include "stdio.h" #include "string.h" #include <sys/types.h> #in ...
- JAVA 主函数(主方法)
主函数(主方法) 1.public (访问修饰符,公共的)代表该类或者该方法访问权限是最大的 2.static 代表主函数随着类的加载而加载 3.void 代表主函数没有具体的返回 ...
- linux ps命令(转载)
来源:http://www.cnblogs.com/peida/archive/2012/12/19/2824418.html Linux中的ps命令是Process Status的缩写.ps命令用来 ...
- 词典对象 NSDictionary与NSMutableDictionary
做过Java语言或者 C语言开发的朋友应该很清楚关键字map 吧,它可以将数据以键值对儿的形式储存起来,取值的时候通过KEY就可以直接拿到对应的值,非常方便,是一种非常常用的数据结构.在Objecti ...
- Jquery动态进行图片缩略
//页面加载完执行resizeImage()函数 $(document).ready(resizeImage()); function resizeImage(){ $(".pic a im ...
- angularjs ng-select ng-options 默认选中项.
<!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="utf- ...
- div的contenteditable和placeholder蹦出的火花
今天在做手机端发布描述内容时,需要实现换行,还需要有plachholder. 在文本框中换行自然想到了textarea. 问题似乎已经解决了,但是当内容发布后,在html中显示换行都丢失了. 这个时候 ...
- gradle android
从github下载两个开源项目: PagerSlidingTabStrip | Android-Universal-Image-Loader-master https://github.c ...