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. 使用swf与swc引入资源的区别[as3]

    SWF用于运行时加载,而SWC在编译时用做外部库.使用SWC库,只有当类被引用,才编译入主程序中. getDefinition: 在使用swc库方式引入资源时,getDefinitionByName反 ...

  2. 清除BOM头源码

    BOM: Byte Order Mark UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是 ...

  3. mvc获取时间戳

    DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(, , )); DateTime dtNow = DateTime.Parse(Date ...

  4. eclipse中如何修改dynamic web module version

    java项目中,若切换服务器,经常会涉及到动态web模块版本的问题.      比如:新建了web项目,开始使用tomcat服务器,但是后来使用jboss服务器,就会出现:Project facet ...

  5. java类集框架图(google找的,备个份)

  6. BizTalk开发系列(六) BizTalk开发简述

    现在很多大型企业信息化程度很高,运行中的系统可达到数十乃至上百个.而大部分系统由于建设的时间.开发团队和技术 往往不相同,系统之间的大部分都是独立运行的.随着信息化建设的深入各系统之间的交互需求越来越 ...

  7. Android课程---首学开发

    新建一个Activity2类: package com.hanqi.test; import android.app.Activity; import android.os.Bundle; impor ...

  8. 精通JavaScript的this关键字

    小提示 阅读本文,您需要了解JS的基本常识.您将花费40分钟完成本文的阅读. JS中的this关键字让很多新老JS开发人员都感到困惑.这篇文章将对this关键字进行完整地阐述.读完本文以后,您的困惑将 ...

  9. ios-改变button四个角的弧度

    -(void)createTitleView{ UIView * backview = [[UIView alloc]init]; backview.frame =CGRectMake(87*kHei ...

  10. MySQL- -Join语法解析与性能分析

    Mysql Join语法解析与性能分析 一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ...