Java容器类解析
1:集合
Collection(单列集合)
List(有序,可重复)
ArrayList
底层数据结构是数组,默认长度是十
查询快,增删慢
add()时判断是否数组越界,数组扩容为原来的1.5倍
线程不安全,效率高
Vector
底层数据结构是数组,查询快,增删慢
线程安全,效率低
LinkedList
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
Set(无序,唯一)
HashSet
底层数据结构是哈希表。
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
是false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可 LinkedHashSet
底层数据结构由链表和哈希表组成。
由链表保证元素有序。
由哈希表保证元素唯一。
TreeSet
底层数据结构是红黑树。(是一种自平衡的二叉树)
如何保证元素唯一性呢?
根据比较的返回值是否是0来决定
如何保证元素的排序呢?
两种方式
自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
比较器排序(集合具备比较性)
让集合接收一个Comparator的实现类对象
Map(双列集合)
A:Map集合的数据结构仅仅针对键有效,与值无关。
B:存储的是键值对形式的元素,键唯一,值可重复。 HashMap
底层数据结构是哈希表。线程不安全,效率高
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,添加到value值链上
是false:就直接添加到集合
否:就直接添加
最终:
自动生成hashCode()和equals()即可
LinkedHashMap
底层数据结构由链表和哈希表组成。
由链表保证元素有序。
由哈希表保证元素唯一。
Hashtable
底层数据结构是哈希表。线程安全,效率低
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
是false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
TreeMap
底层数据结构是红黑树。(是一种自平衡的二叉树)
如何保证元素唯一性呢?
根据比较的返回值是否是0来决定
如何保证元素的排序呢?
两种方式
自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
比较器排序(集合具备比较性)
让集合接收一个Comparator的实现类对象 2.关于集合选取原则 是否是键值对象形式:
是:Map
键是否需要排序:
是:TreeMap
否:HashMap
不知道,就使用HashMap。 否:Collection
元素是否唯一:
是:Set
元素是否需要排序:
是:TreeSet
否:HashSet
不知道,就使用HashSet 否:List
要安全吗:
是:Vector
否:ArrayList或者LinkedList
增删多:LinkedList
查询多:ArrayList
不知道,就使用ArrayList
不知道,就使用ArrayList 3:集合的常见方法及遍历方式
Collection:
add()
remove()
contains()
iterator()
size() 遍历: for Map 遍历:
根据键找值
根据键值对对象分别找键和值
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
在这里说一点,接口可以多继承其他接口的。
1、Iterator接口
Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。
iterator.remove()方法:在对list集合使用iterator遍历时,如果调用Iterator 的remove() 方法来删除的话,则iterator的内部对象个数和原来集合中对象的个数会保持同步,而直接调用集合的remove方法来删除的话,集合中对象的个数会变化而Iterator 内部对象的个数不会变化,当调用Iterator 的next 遍历的时候发现集合中的对象的个数和Iterator 内部对象的个数不同,这样指针往后移动的时候就找不到要迭代的对象。这是报异常的主要原因,但 内部对象操作时为了避免这种情况都会通过checkForComodification方法检测是否一致,不一致提前抛出异常ConcurrentModifiedException
它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果是先Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList。
抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流大大降低。
2、Colection接口
容器继承关系中的顶层接口。是一组对象元素组。有些容器允许重复元素有的不允许,有些有序有些无序。 JDK不直接提供对于这个接口的实现,但是提供继承与该接口的子接口比如 List Set。这个接口的设计目的是希望能最大程度抽象出元素的操作。
List接口
一组元素是有序的、可重复的集合
List继承了abstractList,也继承了LinkIterator,有了listIterator方法,可以在迭代时对list进行删除修改操作。
public static void main(String[] args) {
ArrayList al=new ArrayList();
al.add("java03");
al.add("java02");
al.add("java01");
ListIterator li=al.listIterator();//-----该迭代器中有add()、set()等方法都可以使用
while(li.hasNext()){
Object o=li.next();
if(o.equals("java03")){
li.add("java04");//li.remove()//li.set("java04")
} } System.out.println(al);//------------------>[java01, java02, java03, java04] }
Vector 和 ArrayList的区别吧,反正也没什么卵用,大家看看就好
- Vector 出生早,JDK1.0的时候出生的,ArrayList 是1.2才出生
- Vector 是线程安全的,ArrayList 不是。(这是最大的特点了)
- Vector 默认扩容2倍,ArrayList 是1.5倍。这个~~有意义吗?
- Vector 多了一种迭代器 Enumeration。好吧,反正我没用过。Enumeration 就像是线程安全的Iterator
linkedList 链表结构,找到一个元素后,自动关联下一个元素,链状结构。
Set(无序,唯一)
HashSet 底层数据结构是哈希表(HashMap)。哈希表依赖两个方法:hashCode()和equals()
执行顺序:首先判断hashCode()值是否相同,不是则继续执行equals(),看equals其返回值是false,是则直接添加到集合
LinkedHashSet 底层数据结构是链表和哈希表(LinkedHashMap)
TreeSet 底层数据结构是红黑树(TreeMap)
Queue
队列,先入先出,FIFO,由linkedList实现,LinkedList采用双向链表,本身就有addFirst addLast getFirst getLast等功能的需求,而队列是只是特定功能的LinkedList,二者实现的方法都是一样
public interface Queue<E> extends Collection<E> { boolean add(E e); // 添加元素到队列中,相当于进入队尾排队。 boolean offer(E e); //添加元素到队列中,相当于进入队尾排队. E remove(); //移除队头元素 E poll(); //移除队头元素 E element(); //获取但不移除队列头的元素 E peek(); //获取但不移除队列头的元素
}
3 Map接口
在上面途中,看到map有箭头指向collection,这是因为map的实现依赖collection,数据结构与collection不同
集合存储键值对。一对一对往里存。而且要保证键的唯一性。
keySet()用于返回键的Set集合;
values()用于返回值的Set集合;
entrySet()用于返回键值集的Set集合,键值信息封装在Map.Entry中。
HashMap
初始容量值:16,加载因子0.75f,扩容两倍
存数据时,根据key经过hash得到数值,放到数组中,如果遇到冲突则以链表方式挂在下方;
LinkedHashMap
初始容量16,加载因子0.75f,扩容两倍。一个有序的map,继承HashMap,LinkedHashMap并未重写父类HashMap的put方法,而是重写了父类HashMap的put方法调用的子方法void addEntry(int hash, K key, V value, int bucketIndex) 和void createEntry(int hash, K key, V value, int bucketIndex),提供了自己特有的双向链接列表的实现(LinkedHashMap多维护了一份head,tail链表)
WeakHashMap,此种Map的特点是,当除了自身有对key的引用外,此key没有其他引用那么此map会自动丢弃此值,
举例:声明了两个Map对象,一个是HashMap,一个是WeakHashMap,同时向两个map中放入a、b两个对象,当HashMap remove掉a 并且将a、b都指向null时,WeakHashMap中的a将自动被回收掉。出现这个状况的原因是,对于a对象而言,当HashMap remove掉并且将a指向null后,除了WeakHashMap中还保存a外已经没有指向a的指针了,所以WeakHashMap会自动舍弃掉a,而对于b对象虽然指向了null,但HashMap中还有指向b的指针,所以WeakHashMap将会保留b
4、集合工具类
Collections:集合框架的工具类。里面定义的都是静态方法。
Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
——List:对元素都有定义索引。有序的。可以重复元素。
——Set:不可以重复元素。无序。
Collections是集合框架中的一个工具类。该类中的方法都是静态的。
提供的方法中有可以对list集合进行排序,二分查找等方法。
通常常用的集合都是线程不安全的。因为要提高效率。
如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
Java容器类解析的更多相关文章
- java容器类---概述
1.容器类关系图 虚线框表示接口. 实线框表示实体类. 粗线框表示最经常使用的实体类. 点线的箭头表示实现了这个接口. 实线箭头表示类能够制造箭头所指的那个类的对象. Java集合工具包位于Java. ...
- Java容器解析系列(0) 开篇
最近刚好学习完成数据结构与算法相关内容: Data-Structures-and-Algorithm-Analysis 想结合Java中的容器类加深一下理解,因为之前对Java的容器类理解不是很深刻, ...
- Java Sax解析
一. Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode.如下面的这段boo ...
- Java XML解析工具 dom4j介绍及使用实例
Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...
- Java容器类接口的选择
我们知道Java容器类实际提供了四类接口:Map,List,Set和Queue,如下图所示,每种接口都有不止一个版本的实现,如果在实际编写程序时需要使用某种接口时该如何选择. 从Oracle的Java ...
- Java容器类概述
1.简介 容器是一种在一个单元里处理一组复杂元素的对象.使用集合框架理论上能够减少编程工作量,提高程序的速度和质量,毕竟类库帮我们实现的集合在一定程度上时最优的.在Java中通过java.util为用 ...
- java 容器类大集结
这个世界是程序员的世界,归根到底是数据的世界,要统治这个世界,首先要学会征服数据. 没有最好的,只有最合适的,如何在不同的环境先选择最优的存储的结构呢?且看下文分解: 以下内容部分来自网络,参考: h ...
- 【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别
原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,Hash ...
- Java泛型解析(03):虚拟机运行泛型代码
Java泛型解析(03):虚拟机运行泛型代码 Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...
随机推荐
- 为什么使用centos部署服务器
这个是实验室同学面试的时候,面试官问的一个问题? 为什么选择centos系统,为什么centos系统用的比较多呢? 首先我们说下redhat红帽公司,它是全球最大的linux服务提供商,它的服务是最好 ...
- hadoop设置公平队列
http://hadoop.apache.org/docs/r1.2.1/fair_scheduler.html fair-scheduler.xml文档 <?xml version=" ...
- HDU1540 区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- 使用VS2010编译MongoDB C++驱动详解
最近为了解决IM消息记录的高速度写入.多文档类型支持的需求,决定使用MongoDB来解决. 考虑到MongoDB对VS版本要求较高,与我现有的VS版本不兼容,在leveldb.ssdb.redis.h ...
- Cropper
jQuery.cropper是一款使用简单且功能强大的图片剪裁jQuery插件.该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用. 官网:https ...
- LightOJ 1375 - LCM Extreme 莫比乌斯反演或欧拉扩展
题意:给出n [1,3*1e6] 求 并模2^64. 思路:先手写出算式 观察发现可以化成 那么关键在于如何求得i为1~n的lcm(i,n)之和.可以知道lcm(a,b)为ab/gcd(a,b) 变换 ...
- java将文件转为UTF8工具类
package hiveTest; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File ...
- Sass 颜色函数
/* * Sass 颜色函数 * RGB 颜色函数 * 1. rgb($red,$green,$blue):根据红.绿.蓝三个值创建一个颜色: * rgb(200,40,88) //根据r:200,g ...
- Redis 键值数据类型及基本操作
到目前为止,Redis 支持的键值数据类型如下: 字符串(String) 哈希(Map) 列表(list) 集合(sets) 有序集合(sorted sets) 1. String 字符串类型 s ...
- 【BZOJ1449&&2895】球队预算 [费用流]
球队预算 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在一个篮球联赛里,有n支球队, 球 ...