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用法以及区别(转)的更多相关文章

  1. Collection List Set和Map用法与区别

    labels:Collection List Set和Map用法与区别 java 散列表 集合 Collection           接 口的接口      对 象的集合   ├   List   ...

  2. List,Set,Map用法以及区别

    List,Set,Map是否继承自Collection接口? 答:List,Set是,Map不是. 如图: Collection ├List │├LinkedList │├ArrayList │└Ve ...

  3. java中List,Set,Map用法以及区别

    List,Set,Map是否继承自Collection接口? 答:List,Set是,Map不是. Collection是最基本的集合接口,一个Collection代表一组Object,即Collec ...

  4. 【Java集合的详细研究8】List,Set,Map用法以及区别

    Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素.一些Collection允许相同的元素而另一些不行.一些能排序而另一些不行.Java ...

  5. ES6中Set 和 Map用法

    JS中Set与Map用法 一.Set 1.基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. ...

  6. [转载]jQuery中wrap、wrapAll和wrapInner用法以及区别

    原文地址:jQuery中wrap.wrapAll和wrapInner用法以及区别作者:伊少君 原文: <ul>   <li title='苹果'>苹果</li>   ...

  7. Java中Set Map List 的区别

    java中set map list的区别: 都是集合接口 简要说明 set --其中的值不允许重复,无序的数据结构 list   --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构 ...

  8. WordPress翻译中 __()、_e()、_x、_ex 和 _n 的用法及区别

    编译函数 WordPress使用了下面几个函数来方便语言本地化. __() _e() _x() _ex() _n() 以上所列的函数是用来包含所需翻译的字符串的,根据字符串的不同参数和输出类型,需要使 ...

  9. typedef和#define的用法与区别

    typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程 ...

随机推荐

  1. Python中的socket 模块

    Python 提供了两个基本的 socket 模块.第一个是 Socket,它提供了标准的 BSD Sockets API.第二个是 SocketServer, 它提供了服务器中心类,可以简化网络服务 ...

  2. MVVM deep dive

    You can get a different instance each time by passing a different key to the GetInstance method. How ...

  3. java script小结

    javascript是一种嵌入在网页里的程序段,是一种解释性语言,只能被浏览器解释执行.出于安全性的考虑,增加了javascript的限制,增强了客户端交互功能. JavaScript的作用: 1.增 ...

  4. 处理海量数据的高级排序之——堆排序(C++)

    在面对大数据量的排序时(100W以上量级数据),通常用以下三种的排序方法效率最高O(nlogn):快速排序.归并排序,堆排序.在这个量级上,其他冒泡,选择,插入等简单排序已经无法胜任,效率极低,跟前面 ...

  5. Listener监听器使用小案例

    这里介绍的就是一个客户流失监听器案例 新建一个监听器实现ServletContextListener接口 覆写contextDestroyed和contextInitialized 方法 packag ...

  6. 完美扫描PHP特殊一句话后门

    <?php /********************** 作者 Spider 网上公布的各种PHP后门全军覆没 针对一些特殊变形的后门需要自己添加特征 误报率不到百分之一 ********** ...

  7. 笔记本(WIN7|XP)发射wifi信号 当无线路由使用

    Windows7系统 第一步:是你的电脑上要有两个网卡一个有线一个无线(笔记本应该都有)台式机可以考虑买个USB无线网卡(50左右) 第二步:win+R  CMD  输入(只输入红色部分) netsh ...

  8. 解决Android调用https服务API时出错的问题

    今天同事告诉我说他的应用调用我开发的API报异常了,原因跟SSL有关系,因为之前调试一直调用的是HTTP服务API,今天调试HTTPS服务API时报错了,并且找到了一篇文章让我看了一眼,文章中提到了W ...

  9. win2003远程桌面端口修改

    win2003远程桌面端口修改   1.改端口:简单操作步骤:打开"开始→运行",输入"regedit",打开注册表,进入以下路径:[HKEY_LOCAL_MA ...

  10. 【iCore3双核心板】【4.3寸液晶驱动板爆照!】

     [源代码完全开源,过几天连同硬件一起发布] 花了好久的时间,我们的fpga工程师才完成这液晶模块的驱动代码,其核心价值如下: 1.完全基于fpga驱动,sdram当做缓存: 2.内建双缓冲机制:方便 ...