Connection&Map集合类

1.集合类概述
   当你事先不知道要存放数据的个数,或者你需要一种比数组下标存取机制更灵活的方法时,你就需要用到集合类。
集合类型主要有3种:set(集)、list(列表)和map(映射),set和list是继承自connection接口的,存放于java.util包中。
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements,Map提供key到value的映射

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

 

2.Connection
  2.1.List
    (1)Vector:基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能走入Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就是Vector“sychronized”的,这个也是Vector和ArrayList的唯一的区别。
    (2)Stack: 这个类从Vector派生而来,并且增加了方法实现栈??一种后进先出的存储结构。
    (3)ArrayList:同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自

己在管理线程的同步问题。
    (4)LinkedList:LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这就是LinkedList的优势。


  List总结:
    a. 所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ];
    b. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ];
    c. 所有的List中可以有null元素,例如[ tom,null,1 ];
    d. 基于Array的List(Vector,ArrayList)(顺序表)适合查询,而LinkedList(链表)适合添加,删除操作。

 

  注意:ArrayList与Vector不同点
      a.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
      b.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半
 
  2.2.Set
    (1)HashSet:虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。看看HashSet的add(Object obj)方法的实现就可以一目了然了。
      public boolean add(Object obj)
      {
          return map.put(obj, PRESENT) == null;
      }
这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。
    (2)LinkedHashSet:HashSet的一个子类,一个链表。
    (3)TreeSet:SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。

 

  Set总结:
    a.Set实现的基础是Map(HashMap);
    b.Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

 

  2.3.迭代器iterator
    通常遍历List和Set都是使用迭代器iterator进行遍历

Iterator it = list.iterator();
while(it.hasNext())
{
  Object o=(Object)it.next();
  ...
}


  另外注意list和set的一些常用方法:

boolean add(Object)//确保容器持有此参数。如果没有将此参数添加进容器则返回false。
boolean addAll(Collection)//添加参数中的所有元素。只要添加了任意元素就返回true。
void clear( )//移除容器中的所有元素.
boolean contains(Object)//如果容器已经持有参数则返回true
boolean containsAll(Collection)//如果容器持有参数中的所有元素则返回true
boolean isEmpty( )//容器中没有元素时返回true
Iterator iterator( )//返回一个Iterator,可以用来遍历容器中的元素。
boolean remove(Object)//如果参数在容器中,则移除此元素的一个实例。如果做了移除动作则返回true。
boolean removeAll(Collection)//移除参数中的所有元素。只要有移除动作发生就返回true.
boolean retainAll(Collection)//只保存参数中的元素只要Collection发生了改变就返回true.
int size( )//返回容器中元素的数目
Object[] toArray( )//返回一个数组,包含容器中的所有元素。
Object[] toArray(Object[] a)//返回一个数组,包含容器中的所有元素,其类型与数组a的类型相同,而不是单纯的Object


3.Map
  3.1.常用Map简介
    (1)HashTable:实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。
    (2)HashMap:实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。
    (3)WeakHashMap:实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。
    (4)TreeMap:实现这样一个映象,对象是按键升序排列的
   
  注意:HashMap与HashTable的不同点:
      a.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
      b.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
      c.值:只有HashMap可以让你将空值作为一个表的条目的key或value

 

  3.2.Map接口常用方法介绍
    我们先介绍一下 Map 接口本身,以便了解所有实现的共同点。 Map 接口定义了四种类型的方法,每个 Map 都包含这些方法。
    (1)覆盖和比较的方法
      equals(Object o):比较指定对象与此 Map 的等价性
      hashCode():返回此 Map 的哈希码
    (2)构建和更新的方法
      put(Object key, Object value):将指定值与指定键相关联
      putAll(Map t):将指定 Map 中的所有映射复制到此 map
      remove(Object key):从 Map 中删除键和关联的值
      clear():从 Map 中删除所有映射
    (3)迭代与检索的方法
       迭代Map并没有最直接的方法,一般是通过以下三种视图:
      Set entrySet():有键值对       Iterator keyValuePairs = aMap.entrySet().iterator();
      Set keySet():所有键            Iterator keys = aMap.keySet().iterator();
      Connection values():所有值    Iterator values = aMap.values().iterator(); 
  

 int mapsize = aMap.size(); 

Iterator keyValuePairs1 = aMap.entrySet().iterator(); 
for (int i = 0; i < mapsize; i++) 
{ 
Map.Entry entry = (Map.Entry) keyValuePairs1.next(); 
Object key = entry.getKey(); 
Object value = entry.getValue(); 
... 
} 

Object[] keyValuePairs2 = aMap.entrySet().toArray(); 
for (int i = 0; i < rem; i++) { 
{ 
Map.Entry entry = (Map.Entry) keyValuePairs2[i]; 
Object key = entry.getKey(); 


Object value = entry.getValue(); 
... 
} 
//(通常第一种方法比第二种方法要快一些)

 
    (4)访问和测试的方法
      get(Object key):返回与指定键关联的值
      containsKey(Object key):假如 Map 包含指定键的映射,则返回 true
      containsValue(Object value):假如此 Map 将一个或多个键映射到指定值,则返回 true (containsValue比containsKey时间长得多)
      isEmpty():假如 Map 不包含键-值映射,则返回 true
      size():返回 Map 中的键-值映射的数目
 
  3.3.内部哈希: 哈希映射技术

    几乎所有通用 Map 都使用哈希映射。 这是一种将元素映射到数组的非常简单的机制,您应了解哈希映射的工作原理,以便充分利用 Map。

    哈希映射结构由一个存储元素的内部数组组成。 由于内部采用数组存储,因此必然存在一个用于确定任意键访问数组的索引机制。 实际上,该机制需要提供一个小于数组大小的整数索引值。 该机制称作哈希函数。 在 Java 基于哈希的 Map 中,哈希函数将对象转换为一个适合内部数组的整数。 您不必为寻找一个易于使用的哈希函数而大伤脑筋: 每个对象都包含一个返回整数值的 hashCode() 方法。 要将该值映射到数组,只需将其转换为一个正值,然后在将该值除以数组大小后取余数即可。 以下是一个简单的、适用于任何

    对象的 Java 哈希函数

int hashvalue = Maths.abs(key.hashCode()) % table.length;

(% 二进制运算符(称作模)将左侧的值除以右侧的值,然后返回整数形式的余数。)
    实际上,在 1.4 版发布之前,这就是各种基于哈希的 Map 类所使用的哈希函数。 但假如您查看一下代码,您将看到
int hashvalue = (key.hashCode() & 0x7FFFFFFF) % table.length;
它实际上是使用更快机制获取正值的同一函数。 在 1.4 版中,HashMap 类实现使用一个不同且更复杂的哈希函数,该函数基于

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值