List,Set,Map用法以及区别(转)
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java JDK不能提供直接继承自Collection的类,Java JDK提供的类都是继承自Collection的"子接口",如:List和Set。
注意:Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当做一组key集合,一组value集合,或者一组key-value映射。
详细介绍:
List特点:元素有放入顺序,元素可重复
Map特点:元素按键值对存储,无放入顺序
Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
List接口有三个实现类:LinkedList,ArrayList,Vector
LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢
ArrayList和Vector的区别:ArrayList是非线程安全的,效率高;Vector是基于线程安全的,效率低
Set接口有两个实现类:HashSet(底层由HashMap实现),LinkedHashSet
SortedSet接口有一个实现类:TreeSet(底层由平衡二叉树实现)
Query接口有一个实现类:LinkList
Map接口有三个实现类:HashMap,HashTable,LinkeHashMap
HashMap非线程安全,高效,支持null;HashTable线程安全,低效,不支持null
SortedMap有一个实现类:TreeMap
其实最主要的是,list是用来处理序列的,而set是用来处理集的。Map是知道的,存储的是键值对
set 一般无序不重复.map kv 结构 list 有序
Java复习笔记——容器知识点总结
Java中容器分两类,一种是单值的Collection,一种是储存键-值对的Map
Collection
又分两种,Set和List,区别在于Set是不可重复的,而List是可重复的
Set
常用有两种:HashSet和TreeSet,其内部实现是一个Map,它的元素就相当于Map中的Key,而Value是一个Object常量
|
1
2
3
4
5
6
7
|
private transient HashMap<E,Object> map;private static final Object PRESENT = new Object();public HashSet() { map = new HashMap<E,Object>();} |
|
1
2
3
4
5
6
7
|
private transient NavigableMap<E,Object> m;private static final Object PRESENT = new Object();public TreeSet() { this(new TreeMap<E,Object>());} |
所有对Set的操作都被最终转嫁为对Map的操作,具体细节在下面Map中讲述
List
对Collection接口进行了简单的扩充,你可以将任何对象放到放到一个List容器中,并在需要时从中取出。
常用的有ArrayList和LinkedList,都是有顺序,可重复的集合类型
ArrayList:顾名思义,数据列表,其实就是封装了一个数组,因此它的访问速度极快
|
1
2
3
|
private transient Object[] elementData;private int size; |
然后封装了一些对数组的常用操作如插入、删除等。
说到ArrayList不得不提下Arrays类和数组[]
ArrayList可以储存不同类型的对象(虽然一般不推荐这样做),而数组只能是同一类型
ArrayList可以动态增加长度,但效率不高,而数组只能是固定长度,却十分高效。每当执行add/insert等添加元素的方法,都会先检查数组长度是否足够,如果是,它就会以当前容量的3/2倍+1来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。
ArrayList提供常用方法,add/get/indexOf/remove等,而相应的Arrays没有提供add和remove方法,查询元素索引要先sort再binarySearch
ArrayList排序需外部方法Collections.sort(..),数组排序则使用Arrays.sort(..),二者都可以使用自然顺序(实现Comparable)或用Comparator指定
LinkedList:很显然的是链表,内部实现是带头结点的双向链表,适合于在链表中间需要频繁进行插入和删除操作
|
1
2
3
4
5
6
7
8
9
10
11
12
|
private transient Entry<E> header = new Entry<E>(null, null, null);private transient int size = 0;private static class Entry<E> { E element; Entry<E> next; Entry<E> previous;//..} |
Map
是一种把键和值对象进行关联的容器,类比Collection,可以这样说:Collection对象中某个值的ID是它在容器中的索引值,而在Map中,某个值的ID是它对应的键。这样我们使用Map时就不用局限于int型的索引值,可以用任何类型的对象作索引。正是由于Key的索引特性,Map中不允许有同值的Key存在(前文讲到Set内部实现是Map中的Key的集合,所以Set的元素不能重复)。当然,Value是可以重复的,甚至可以是同一个Reference。Map在处理相同的Key时,将新值存入,旧值被替换并返回。
HashMap:采用Hash算法,以便快速查找某个元素。
将键的哈希值作为内存索引依据,内部实现是一个适当长度的链式数组,由Key的Hash值对应数组下标,再间接对应内存,是一种比较高效的存取方式。Key的hashCode()相同的情况下,放在同一个单项链表结构中。
一个HashMap中Key的类型应该重写hashCode()方法,保证在两个对象equals为true时返回相同的值,否则在重复性检查时会直接被当做不同的键,造成不可预期的后果。
Hash容器中判断重复的方式:
先比较hash(key.hashCode())是否相同,hash(int)是一个内部算法,具体细节不作讨论
不同,则不重复
相同,则
比较两个Key是否是同一引用
是,则重复
不是,再调用equals方法
返回true则重复
返回false则不重复
TreeMap:采用树型储存结构按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。
内部实现是一颗二叉排序树,其中序遍历结果为递增序列。所以要求他的Key必须是Comparable或者创建TreeMap的时候指定Comparator。
当Key实现Comparable<E>接口时,必须实现comparaTo(E e)方法,当使用外部比较器(Comparator<T>)时,需实现Comparator<T>的compare(T t1, T t2)方法
相关知识
泛型(Generic)
泛型允许Coding的时候可以定义一些可变的类型,但必须在使用前进行声明具体是哪种类型
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class testGeneric<T> { T t; testGeneric(T t) { this.t = t; }}class test { testGeneric<String> tgs = new testGeneric("Hi,Gineric!"); testGeneric<Integer> tgi = new testGeneric(100);//AutoBoxing { System.out.println(tgs.t);//Output:Hi,Gineric! System.out.println(tgi.t);//AutoUnBoxing&Output:100 }} |
需要注意Java 泛型的类型参数之实际类型在编译时会被消除(upcast to Object),所以无法在运行时得知其类型参数的类型。Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。
迭代器(Iterator)
提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
对于遍历一个容器中所有的元素,Iterator模式是首选的方式
Collection定义了Iterator<E> iterator()方法,子类都各自实现了该方法,我们直接调用即可
Map中虽没有定义,我们可以利用map.entrySet()的iterator()方法
|
1
2
3
4
5
6
7
|
Iterator i = someMap.entrySet().iterator();while(i.hasNext()) { Map.Entry entry = (Map.Entry) i.next(); Object key = i.getKey(); Object value = i.getValue(); //something TODO} |
或者转换为Collection(Set)用增强For循环
|
1
2
3
4
5
6
|
Set<Map.Entry> entrySet = someMap.entrySet();for(Map.Entry entry : entrySet){ Object key = entry.getKey(); Object value = entry.getValue(); //something TODO} |
ListIterator继承了Iterator,提供了对List的双向遍历的方法。
需要注意的是,调用Iterator的remove方法,删除的是最后一次调用next()(or previous(),if possible)所返回的元素
如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的 collection,则迭代器的行为是不确定的。
也就是说,调用Iterator时,最好不要调用Collection的add/remove等方法
另:容器类的toString()方法也是通过调用iterator()方法来实现遍历
对集合使用增强的for循环也是隐式地调用iterator()方法
转自:http://mingcn.cnblogs.com/archive/2010/10/22/JavaContainer.html
List,Set,Map用法以及区别(转)的更多相关文章
- Collection List Set和Map用法与区别
labels:Collection List Set和Map用法与区别 java 散列表 集合 Collection 接 口的接口 对 象的集合 ├ List ...
- List,Set,Map用法以及区别
List,Set,Map是否继承自Collection接口? 答:List,Set是,Map不是. 如图: Collection ├List │├LinkedList │├ArrayList │└Ve ...
- java中List,Set,Map用法以及区别
List,Set,Map是否继承自Collection接口? 答:List,Set是,Map不是. Collection是最基本的集合接口,一个Collection代表一组Object,即Collec ...
- 【Java集合的详细研究8】List,Set,Map用法以及区别
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素.一些Collection允许相同的元素而另一些不行.一些能排序而另一些不行.Java ...
- ES6中Set 和 Map用法
JS中Set与Map用法 一.Set 1.基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. ...
- [转载]jQuery中wrap、wrapAll和wrapInner用法以及区别
原文地址:jQuery中wrap.wrapAll和wrapInner用法以及区别作者:伊少君 原文: <ul> <li title='苹果'>苹果</li> ...
- Java中Set Map List 的区别
java中set map list的区别: 都是集合接口 简要说明 set --其中的值不允许重复,无序的数据结构 list --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构 ...
- WordPress翻译中 __()、_e()、_x、_ex 和 _n 的用法及区别
编译函数 WordPress使用了下面几个函数来方便语言本地化. __() _e() _x() _ex() _n() 以上所列的函数是用来包含所需翻译的字符串的,根据字符串的不同参数和输出类型,需要使 ...
- typedef和#define的用法与区别
typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程 ...
随机推荐
- 【Hihocoder】1014 : Trie树
问题:http://hihocoder.com/problemset/problem/1014 给定一个字符串字典dict,输入字符串str, 要求从dict中找出所有以str为前缀的字符串个数. 构 ...
- scroll、offset和client的区别
整体布局: <!DOCTYPE> <head> <meta http-equiv="Content-Type" content="text/ ...
- thinkphp框架验证码验证一次
做异步验证验证码,只要验证一次结果正确,拿相同的值再次来对比,返回结果就不正确.我看到论坛中有人说,tp框架只要验证过一次正确后验证码就销毁了.确实是这个效果,但具体的还没深入了解
- Rails problem
总是wa~ #include <stdio.h> int main() { ]; ], b[]; while(scanf("%d %s %s", &n, a, ...
- 20145337《Java程序设计》第八周学习总结
20145337<Java程序设计>第八周学习总结 教材学习内容总结 15.1日志 15.1.1日志API简介 使用日志的起点是logger类,logger实例的创建有许多要处理的要素,必 ...
- BizTalk开发系列(十四) XML空白字符(WhiteSpace)
最近在做一个BizTalk项目,对XML文件的处理很复杂.本来是想找有没有方法可以一次性去除XML文件中节点和属性的值的空格.但是找了很久没有看到相关的方法.如果有知道该方法的麻烦跟我讲一下:cbcy ...
- WEB应用中的普通Java程序如何读取资源文件
package cn.itcast; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Serv ...
- VS2010 更改C#类库模板
首先你找到你自己的 VS2010安装目录,例如我本地是: D:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTem ...
- Ffmpeg
Ffmpeg <?php $movefile = "./4.mp4"; $mov = new ffmpeg_movie($movefile); printf("fi ...
- ssm maven项目启动 报SYSTEM_PROPERTIES_MODE_ENVIRONMENT
1.jar包冲突,查看项目中的jar和pom.xml中配置的jar包 版本,把没用的jar包删掉