自己学习java整理深入集合Connection

常用集合类
    1.List
        1)ArrayList
        2)LinkedList
    2.Map
        1)HashMap
        2)HashTable
        3)TreeMap
        4)LinkedHashMap
    3.Set
        1)HashSet
        2)TreeSet
        3)LinkedHashSet

ArrayList
    1.List接口的可变数组的实现。实现了所有可选列表操作,
    并允许包括null在内的所有元素
    2.非线程安全
    3.底层使用的数据结构为数组
    4.适合查改,弱于增删

ArrayList实现分析
    //用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素
public E set(int index,E element){
    RangeCheck(index);//检查index是否合法
    
    E oldValue = (E) elementData[index];
    elementData[index] = element;
    return oldValue;
}

    //将指定的元素添加到列表的尾部
    //直接添加速度快
public boolean add(E e){
    ensureCapacity(size+1);确保容量满足
    elementData[size++]=e;
    return true;
}

    //将指定的元素插入此列表中的指定位置
    //如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)
    //涉及数组拷贝,插入速度不及add(E element)方法
public void add(int index,E element){
    if(index>size||index<0)
        throw new InddexOutOfBoundsException("Index:"+index+",Size"+size);
    //如果数组长度不足,将进行扩容
    ensureCapacity(size+1);
    System.arraycopy(elementData,index,elementData,index+1,size-index);
    elementData[index] = element;
    size++;    
}
过程:abcd()-->ab()cd-->ab(e)cd   

    //移除此列表中指定位置上的元素
    //涉及数组拷贝
public E remove(int index){
    RangeCheck(index);

    modCount++;
    E oldValue = (E) elementData[index];

    int numMoved  = size-index-1;
    if(numMoved>0)
         System.arraycopy(elementData,index+1,elementData,index,numMoved);
    elementData[--size]=null;

    return oldValue;
}
过程:abcd-->(删除b元素)acdd-->acd

    //数组扩容,按照1.5倍方式扩充。涉及数组拷贝,速度慢
    public void ensureCapacity(int minCapacity){
    modCount++;
    int oldCapacity = elementData.length;
    if(minCapacity>oldCapacity){
        int newCapacity = (oldCapacity*3)/2+1;
        if(newCapacity<minCapacity)
            newCapacity = minCapacity;
    elementData = Arrays.copyOf(elementData,newCapacity);
 }
}


LinkedList
    1.List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括null)
    2.实现Deque接口,为add,poll提供先进先出队列操作以及其他堆栈和双端队列操作
    3.非线程安全
    4.适合增删,弱于查改
LinkedList数据结构

private transient Entry<E>header = new Entry<E>(null,null,null);
private static class Entry<E>{
    E element;
    Entry<E>next;//下一个节点
    Entry<E>previous;前序节点

     //构造方法:目标对象paramE将被放置在paramEntry1之前,paramEntry2之后

    Entry(E paramE,Entry<E>paramEntry1,Entry<E>paramEntry2){
        this.element = paramE;
        this.next = paramEntry1;
        this.previous = paramEntry2;
 }
}
    双端队列      (previous)<--Entry-->(next)

LinkedList实现分析
    //根据序号获取Entry对象
private Entry<E>entry(int paramInt){
    if((paramInt<0)||(paramInt>=this.size)){
         throw new IndexOutOfBoundsException("Index:"+paramInt+"Size:"+this.size);
 }
    Entry localEntry = this.header;
    int i; 
    //最多遍历size/2个元素
    if(paramInt<this.size>>1){
         for(i=0;i<=paramInt;i++)
            localEntry = localEntry.next;
 }else{
    for(i=this.size;i>paramInt;i--)
        localEntry = localEntry.previous;
 }
    return localEntry;
}


    //要添加的元素:paramE
    //目标对象:paramEntry
    //插入速度快
private Entry<E>addBefore(E paramE,Entry<E>paramEntry){
    //要添加的对象,设置其previous和next
    Entry localEntry = new Entry(paramE,paramEntry,paramEntry.previous);

    localEntry.previous.next = localEntry;
    localEntry.next.previous = localEntry;

    this.size +=1;
    this.modCount +=1;
    return localEntry;
}

LinkedList添加元素
    //指定位置添加元素,需要先找到index的元素,然后添加
public void add(int index,E element){
    addBefore(element,(index==size?header:entry(index)));
}
    //队首添加元素
public void addFirst(E paramE){
    addBefore(paramE,this.header.next);
}
    //队尾添加元素
public void addLast(E paramE){
    addBefore(paramE,this.header);
}

LinkedList删除元素
        //删除速度快
private E remove(Entry<E>e){
    if(e ==  header)
        throw new NoSuchEllementException();
         
    E result = e.element; //保留将被移除的节点e的内容
    e.previous.next = e.next;//将前一节点的next引用赋值为e的下一个节点
    e.next.previous = e.previous;//将e的下一个节点的previous赋值为e的上一个节点    
    e.next = e.previous = null;//解除e节点对前后节点的引用
    e.element = null;
    size--;
    modCount++;
    return result;
}
public E remove(){
    return removeFirst();//删除第一个元素
}
public E remove(int index){
    return remove(entry(index));//删除第index个元素
}
public E removeFirst(){
    return remove(header.next);//删除头部下一个
}
public E remove()Last{
    return remove(header.previous);//删除最后一个
}


List的适用范围
    1.ArrayList适用于对于数据查询修改大于数据增删的场合
    2.LinkedList适用于对于数据增删大于数据查询的场合

HashMap
    1.基于哈希表的Map实现。提供所有可选的映射操作,并允许使用null值和null键
    2.非线程安全
    3.不保证映射的顺序,特别是它不保证该顺序恒久不变

HashMap数据结构
    1.通过Hashcode找到数组中的某一元素
    2.通过key的equals方法在链表中找到key对应的value
transient Entry[] table;

static class Entry<K,V>implements Map.Entry<K,V>{
    final K key;
    V value;
    Entry<K,V>next;
    fianl int hash;
    ······
}


HashMap实现分析

public V put(K key,V value){
    if(key == null)//null键视为相同的键
        return putForNullKey(value); //根据key的keyCode重新计算hash值
    int hash = hash(key.hashCode()); //搜索指定hash值在对应table中的索引
    int i = indexFor(hash,table.length);
        //如果i索引处的Entry不为null,通过循环不断遍历e元素的下一个元素
    for(Entry<K,V>e = table[i];e!=null;e =e.next){
    Object k;                         
     //key重复出现则更新其value
    if(e.hash == hash&&((k=e.key)==key||key.equals(k))){
        V.oldValue = e.value;
        e.value = value;
        e.recordAccess(this);
        return oldValue;
    }
}
    modCount++;
    addEntry(hash,key,value,i);
    return null;
}
//hash函数,加入了高位计算,防止低位不变,高位变化时,造成的hash冲突
static int hash(int h){
    h^=(h>>>20)^(h>>>12);
    return h^(h>>>7)^(h>>>4);
}

void addEntry(int hash,K key,V value,int bucketIndex){
    //获取指定bucketIndex索引处的Entry
    Entry<K,V>e = table[bucketIndex];
    //将创建的Entry放入bucketIndex索引处,并让新的Entry指向原来的Entry
    table[bucketIndex] = new Entry<K,V>(hash,key,value,e);
    //如果Map中的key-value对的数量超过了极限
    if(size++ >=threshold)
    //把table对象的长度扩充到原来的2倍
    resize(2*table.length)
}
    //根据hash值查找对应的table位置
static int indexFor(int h,int length){
    return h&(length-1)
}

 //put的反过程
public V get(Object key){
    if(key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for(Entry<K,V>e=table[indexFor(hash,table.length)];e!=null;e=e.next){
        Object k;
        if(e.hash==hash&&((k=e.key)==key||key.equals(k)))
            return e.value;
    }
    return null;
}


HashTable的特点
    1.HashMap和HashTable采用相同的存储机制,二者的实现基本一致
    2.不允许有null值的存在
    3.HashTable是线程安全的,内部的方法基本都是synchronized
    4.迭代器具有强一致性

TreeMap
    1.Map接口的树实现
    2.不允许有null值的存在
    3.非线程安全
    4.键值有序
TreeMap数据结构:红黑树
TreeMap实现分析
    1.Entry是红黑树的节点,它包含了红黑树的6个基本组成成分:key键,value键
    left左孩子,right右孩子,parent父节点,color颜色。Entry节点根据key进行排序
    Entry节点包含的内容为value
    2.红黑树排序时,根据Entry中的key进行排序。Entry中的key比较大小是根据比较器
    comparator来进行判断的
TreeMap的优势
    1.空间利用率高
        1)HashMap的数组大小必须为2的n次方
         2)TreeMap中树的每一个节点就代表了一个元素
    2.性能稳定
        1)Hash碰撞会导致HashMap查询开销提高
        2)HashMap扩容时会rehash,开销高
        3)TreeMap的操作均能在O(log n)内完成
LinkedHashMap
    1.Map接口的哈希表和链接列表实现,提供所有可选的映射操作,并允许使用null值和null键
    2.非线程安全
    3.具有可预知的迭代顺序

LinkedHashMap实现分析

void addEntry(int hash,K key,V value,int bucketIndex){
    //调用create方法,将新元素以双向链表的形式加入到映射中
    createEntry(hash,key,value,bucketIndex);
    Entry<K,V>eldest = header.after;
    if(removeEldestEntry(eldest)){
        removeEntryForKey(eldest.key);    
    }else{
        if(size>=threshold)
            resize(2*table.length);
    }
}
void createEntry(int hash,K key,V value,int bucketIndex){
    HashMap.Entry<K,V>old = table[bucketIndex];
    Entry<K,V>e=new Entry<K,V>(hash,key,value,old);
    table[bucketIndex]=e;
    //调用元素的addBrefore方法,将元素加入到双向链接列表
    e.addBefore(header);
    size++
}
public V get(Object key){
    //调用父类HashMap的getEntry()方法,取得要查找的元素
    Entry<K,V>e = (Entry<K,V>)getEntry(key);
    if(e==null)
        return null;
    //记录访问顺序
    e.recordAccess(this);
    return e.value;
}

void recordAccess(HashMap<K,V>m){
    LinkedHashMap<K,V>Im = (LinkedHashMap<K,V>)m;
    //如果定义了LinkedHashMap的迭代顺序为访问顺序,则删除以前位置上的元素,并将最新访问的元素添加到链表表头
    if(Im.accessOrder){
        Im.modCount++;
        remove();
        addBefore(Im.header);
    }
}


Map的适用范围
    1.HashMap适用于一般的键值映射需求
    2.HashTable适用于有多线程并发的场合
    3.TreeMap适用于要按照键排序的迭代场合
    4.LinkedHashMap适用于特殊顺序的迭代场合(如LRU算法)

HashSet
    1.实现Set接口,由哈希表支持,允许使用null元素
    2.非线程安全
    3.不保证set的迭代顺序,特别是不保证该顺序恒久不变

HashSet实现分析
    //底层使用HashMap来保存HashSet中所有元素
private transient HashMap<E,Object>map;
    //定义一个虚拟的Object对象作为HashMap的value
private static final Object PRESENT = new Object();
    //借助HashMap的add方法来添加
    //HashMap的add方法可以返回该key之前的value值,如果为null则说明之前尚未添加该key,即该HashSet可以添加该元素
public boolean add(E e){
    return map.put(e,PRESENT)==null;
}
    //借助HashMap的方法来查找
public boolean countains(Object o){
    return map.containKey(o);
}


Set的特点
    1.HashSet通过HashMap实现
    2.TreeSet通过TreeMap实现
    3.LinkedHashSet通过LinkedHashMap实现
    4.Set类与Map类拥有近似的使用特性


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
package com.hexiang.utils.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.log4j.Logger; public class DBConnection { /** * 获得与数据库的连接 * * @param path * @return Connection */ public static Connection getConn(String classDriver, String url, String user, String pwd) { try { Class.forName(classDriver); return DriverManager.getConnection(url, user, pwd); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } return null; } public static Connection getConn(DataSource dataSource) { try { return dataSource.getConnection(); } catch (SQLException ex) { ex.printStackTrace(); } return null; } public static Connection getConn(String jndiName) { try { Context ctx; ctx = new InitialContext(); DataSource dataSource = (DataSource) ctx.lookup("java:comp/env/" + jndiName); return dataSource.getConnection(); } catch (NamingException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } return null; } public static Connection getConn(Properties properties) { try { String driver = properties.getProperty("jdbc.driverClassName"); String url = properties.getProperty("jdbc.url"); String user = properties.getProperty("jdbc.username"); String password = properties.getProperty("jdbc.password"); Class.forName(driver); return DriverManager.getConnection(url, user, password); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (SQLException ex) { ex.printStackTrace(); } return null; } /** * oracle连接 * * @param path * @return Connection */ public static Connection getOracleConn(String
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

掉帧且闪退

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值