java集合框架类图

  Collection接口(List、Set、Queue、Stack)

  

  Map接口

Collection集合

1、List

ArrayList(数组)

(1)     增加

1、末尾插入

  public boolean add(E e) {

            ensureCapacity(size + 1);  // Increments modCount!!

            elementData[size++] = e;

            return true;

 }

2、指定位置插入

   public void add(int index, E element) {

    if (index > size || index < 0)

        throw new IndexOutOfBoundsException(

              "Index: "+index+", Size: "+size);

     ensureCapacity(size+1);  // Increments modCount!!

     System.arraycopy(elementData, index, elementData, index + 1,size - index);

     elementData[index] = element;

     size++;

    }

  

 

结论:指定位置插入需要移动大量元素的位置,所以效率不高。

 

(2)     修改

public E set(int index, E element) {

   RangeCheck(index);

   E oldValue = (E) elementData[index];

   elementData[index] = element;

   return oldValue;

}

结论:只能修改已经存在的对象。

 

(3)     删除

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; // Let gc do its work

 

   return oldValue;

}

 

public boolean remove(Object o) {

        if (o == null) {

            for (int index = 0; index < size; index++)

                 if (elementData[index] == null) {

                     fastRemove(index);

                     return true;

                 }

        } else {

            for (int index = 0; index < size; index++)

                 if (o.equals(elementData[index])) {

                     fastRemove(index);

                     return true;

                 }

        }

        return false;

    }

 结论:删除也会移动大量的元素。效率不高

 

(4)     遍历

List<String> strList = new ArrayList<String>();

strList.add(“123”);

for(String str :strList){

           System.out.println(str);

}

总结:为了提高效率。最好为ArrayList的大小赋个初值。

LinkedList(双向链表)

(1)     增加

1、public boolean add(E e) {

   addBefore(e, header);

        return true;

}

 

private Entry<E> addBefore(E e, Entry<E> entry) {

   Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);

   newEntry.previous.next = newEntry;

   newEntry.next.previous = newEntry;

   size++;

   modCount++;

   return newEntry;

}

 

 

 2、  public void addFirst(E e) {

                   addBefore(e, header.next);

                   }

                   public void addLast(E e) {

                   addBefore(e, header);

                  }

 3、指定位置添加数据

            public void add(int index, E element) {

                    addBefore(element, (index==size ? header : entry(index)));

               }

      结论:正常Add(E e)方法就是在链表尾部添加节点。指定位置添加数据不需要移动大量数据。

              只需改变带插入位置前后节点的指针即可。

(2)     删除

   public E remove(int index) {

        return remove(entry(index));

    }

 

    /**

     * Returns the indexed entry.

     */

    private Entry<E> entry(int index) {

        if (index < 0 || index >= size)

            throw new IndexOutOfBoundsException("Index: "+index+

                                                ", Size: "+size);

        Entry<E> e = header;

        if (index < (size >> 1)) {

            for (int i = 0; i <= index; i++)

                e = e.next;

        } else {

            for (int i = size; i > index; i--)

                e = e.previous;

        }

        return e;

}

结论:从前向后遍历删除数据。删除和添加数据时候。不需要移动大量数据。只需遍历,

所以相对于ArrayList效率较高。

 

(3)     修改

  public E set(int index, E element) {

        Entry<E> e = entry(index);

        E oldVal = e.element;

        e.element = element;

        return oldVal;

}

结论:修改相应节点的值

(4)     遍历

略。

2、Set

HashSet(底层由HashMap实现)

   public HashSet() {

           map = new HashMap<E,Object>();

     }

HashSet实现是利用HashMap的Key存储值。Value都是Object

(1)     增加

            参考HashMap实现。

(2)     删除

             参考HashMap实现。

(3)     修改

            参考HashMap实现。

(4)     遍历

            参考HashMap实现。

TreeSet(底层由TreeMap实现)

public TreeSet() {

this(new TreeMap<E,Object>());

}

TreeSet实现是利用TreeMap的Key存储值。Value都是Object

(1)     增加

             参考TreeMap实现。

(2)     删除

            参考TreeMap实现。

(3)     修改

            参考TreeMap实现。

(4)     遍历

             参考TreeMap实现。

 

LinkedHashSet(底层由LinkedHashMap实现)

(1)     增加

            参考LinkedHashMap实现。

(2)     删除

            参考LinkedHashMap实现。

(3)     修改

            参考LinkedHashMap实现。

(4)     遍历

            参考LinkedHashMap实现。

 

3、Queue(先进先出)

   底层数据结构是堆。

4、Stack(后进先出)

 底层有数组实现。

(1)    public synchronized E pop()

         弹出栈顶元素,并删除栈顶元素。

(2)    public synchronized E peek()

         只弹出栈顶元素,不删除。

Map集合

<Key,value>的映射。Key不能重复。Value可以重复。

每对<Key,Value>组成一个单元Entity对象。

将Entity做为一个对象进行存储。

1、HashMap

底层维护一个Entity[]

(1)增加

public V put(K key, V value) {

if (key == null)

return putForNullKey(value);

int hash = hash(key.hashCode());

int i = indexFor(hash, table.length);

for (Entry<K,V> e = table[i]; e != null; e = e.next) {

Object k;

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;

}

void addEntry(int hash, K key, V value, int bucketIndex) {

Entry<K,V> e = table[bucketIndex];

table[bucketIndex] = new Entry<K,V>(hash, key, value, e);

if (size++ >= threshold)

resize(2 * table.length);

}

结论:1允许key为Null,2根据key的hashcode值确定该Entity在数组中的位置。3若该位置存在Key得用newValue替换oldValue。否则插入链表头部

  (2)删除、修改

根据key的hashCode值找到对应的Entity对象。进行修改和删除操作。

  (3)遍历

     

 /**

                    * 1、第一种遍历方法

                    */

                   Set<String> keys = hashMap.keySet();

                   for(String key : keys){

                            System.out.print("key: " + key);

                            System.out.print("value: " + hashMap.get(key));

                            System.out.println();

                   }

                   /**

                    * 2、第二种遍历方法

                    */

                   Set<Map.Entry<String, String>> entrys1 = hashMap.entrySet();

                  

                   for(Map.Entry<String, String> entry : entrys1){

                            System.out.print("key: " + entry.getKey());

                            System.out.print("value: " + entry.getValue());

                            System.out.println();

                   }

                   /**

                    * 3、第三种遍历方法(推荐)

                    */

                   Set<Map.Entry<String, String>> entrys2 = hashMap.entrySet();

                   Iterator<Map.Entry<String, String>> iter = entrys2.iterator();

                   while(iter.hasNext()){

                            Map.Entry<String, String> entry = iter.next();

                            System.out.print("key: " + entry.getKey());

                            System.out.print("value: " + entry.getValue());

                            System.out.println();

                   }

 

2、TreeMap(按Key值的有序排列)

底层由一个红黑树结构构成。每个节点都是一个Entity对象。

(1)     增加

public V put(K key, V value) {

        Entry<K,V> t = root;

        if (t == null) {

       // TBD:

       // 5045147: (coll) Adding null to an empty TreeSet should

       // throw NullPointerException

       //

       // compare(key, key); // type check

            root = new Entry<K,V>(key, value, null);

            size = 1;

            modCount++;

            return null;

        }

        int cmp;

        Entry<K,V> parent;

        // split comparator and comparable paths

        Comparator<? super K> cpr = comparator;

        if (cpr != null) {

            do {

                parent = t;

                cmp = cpr.compare(key, t.key);

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

                else

                    return t.setValue(value);

            } while (t != null);

        }

        else {

            if (key == null)

                throw new NullPointerException();

            Comparable<? super K> k = (Comparable<? super K>) key;

            do {

                parent = t;

                cmp = k.compareTo(t.key);

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

                else

                    return t.setValue(value);

            } while (t != null);

        }

        Entry<K,V> e = new Entry<K,V>(key, value, parent);

        if (cmp < 0)

            parent.left = e;

        else

            parent.right = e;

        fixAfterInsertion(e);

        size++;

        modCount++;

        return null;

}

结论:1、TreeMap支持自定义排序。可以设置实现Comparator接口的自定义排序类。

              如果没有设置自定义排序规则。则按照key值升序排序。

        2、插入数据会进行比较找到待插入的位置。

(2)     删除

删除一个树节点,也会重新调整树结构。所以效率不高。

(3)     修改

略。

(4)     遍历

参考HashMap的遍历

3、LinkedHashMap

继承自HashMap,底层的数据结构与HashMap相似。只不过HashMap是数组中存储单向链表,LinkedHashMap是数组中存储双向链表

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的。

(1)         增加

(2)         删除

(3)         修改

(4)         遍历

4、IdentityHashMap

Map由 key-value组成,key用于检索value的内容。在正常情况下,可以不允许重复;重复在java中分为 2中情况,

一是内存地址重复,另一个是不同的地址但内容相等,而IdentityHashMap用于后者,即内容相等。

更详细的解释如下:在 IdentityHashMap 中,当且仅当 (k1==k2) 时,才认为两个键 k1 和 k2 相等(在正常 Map 实现(如 HashMap)中,当且仅当满足下列条件时才认为两个键 k1 和 k2 相等:(k1==null ? k2==null : e1.equals(e2)))。

此类不是 通用 Map 实现!此类实现 Map 接口时,它有意违反 Map 的常规协定,该协定在比较对象时强制使用 equals 方法。此类设计仅用于其中需要引用相等性语义的罕见情况

5、ConcurrentHashMap

concurrenthashmap是一个非常好的map实现,在高并发操作的场景下会有非常好的效率。实现的目的主要是为了避免同步操作时对整个map对象进行锁定从而提高并发访问能力。

ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修 改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可 以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可 变的。HashEntry代表每个hash链中的一个节点,其结构如下所示:

Java代码

  1. static final class HashEntry<K,V> {
  2. final K key;
  3. final int hash;
  4. volatile V value;
  5. final HashEntry<K,V> next;
  6. }

可以看到除了value不是final的,其它值都是final的,这意味着不能从hash链的中间或尾部添加或删除节点,因为这需要修改next 引用值,所有的节点的修改只能从头部开始。对于put操作,可以一律添加到Hash链的头部。但是对于remove操作,可能需要从中间删除一个节点,这就需要将要删除节点的前面所有节点整个复制一遍,最后一个节点指向要删除结点的下一个结点。这在讲解删除操作时还会详述。为了确保读操作能够看到最新的值,将value设置成volatile,这避免了加锁

Iterable接口和Comparator、Comparable接口

1、Iterable接口

public interface Iterator<E> {

boolean hasNext();

E next();

void remove();

}

集合中增强for循环。实际是利用Iterable接口。实现Iterable接口的集合或对象可以使用增强for循环。

2、Comparator、Comparable接口

实现Comparator、Comparable接口的类。可以自定义排序。

集合常用工具类

1、Collections

1)集合的排序

2)集合的二分查找。

3)集合的拷贝

4)集合的反转和旋转。

2、Arrays

Arrays.asList(数组对象)  将Array转化为List类型对象。

         用Collection接口中的toArray方法,将集合转化为数组。

1)数组的排序

2)数组的交换

3)数组的拷贝

4)数组的查找(二分查找等)

Java集合框架类的更多相关文章

  1. Java集合框架类图

    Java集合框架的类图 http://blog.toruneko.net/28

  2. Java集合框架(常用类) JCF

    Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...

  3. 【JAVA集合框架之工具类】

    一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public ...

  4. Java最重要的21个技术点和知识点之JAVA集合框架、异常类、IO

    (三)Java最重要的21个技术点和知识点之JAVA集合框架.异常类.IO  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享 ...

  5. 处理异常、常用类、反射、类加载与垃圾回收、java集合框架

    异常处理概述 检查异常:检查异常通常是用户错误或者不能被程序员所预见的问题.(cheched) 运行时异常:运行时异常是一个程序在运行过程中可能发生的.可以被程序员避免的异常类型.(Unchecked ...

  6. Java集合框架之四大接口、常用实现类

    Java集合框架 <Java集合框架的四大接口> Collection:存储无序的.不唯一的数据:其下有List和Set两大接口. List:存储有序的.不唯一的数据: Set:存储无序的 ...

  7. java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类

    本文关键词: java集合框架  框架设计理念  容器 继承层级结构 继承图 集合框架中的抽象类  主要的实现类 实现类特性   集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...

  8. java集合框架——工具类

    一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public ...

  9. (Set, Map, Collections工具类)JAVA集合框架二

    Java集合框架部分细节总结二 Set 实现类:HashSet,TreeSet HashSet 基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝 ...

随机推荐

  1. git操作详解

    前言:一般公司git的master主干与线上代码保持一致,在使用git的时候,偶尔会发生一些莫名其妙的事情,很容易导致运营事故.so- 总结一下经常使用的git命令以及git的一些小坑,方便日后查阅 ...

  2. iOS9,10没有问题,iOS8上面一登录就崩溃,原因Assets的问题

    在项目中开发中,打包成一个ipa的包,发现iOS9,10,运行非常流畅,iOS8上面一运行就崩溃,找了好久,才找到原因竟然是Assets的问题,一开始我把ipa包放在蒲公英上面托管扫码下载的,用iTu ...

  3. C#研究OpenXML之路(3-OpenXMLSDKToolV25.msi)

    一.OpenXMLSDKToolV25.msi 看了几天的OpenXml,感觉如果完全手写代码,将会是一件非常苦逼的事情,即要分析对应xlsx文件层次结构,以及包含的xml文件的xml标签结构,还要关 ...

  4. Debian 8开启sftp服务

    看到某云的CDN居然是使用ftp这种早该淘汰的协议,不禁有些吐槽.ftp曾经作为互联网上最重要的协议,但漫长使用过程中体现出的各种缺点,已不适合再使用.其中最致命的问题就是明文传输用户密码.建议使用这 ...

  5. 老李分享:开发python的unittest结果输出样式

    老李分享:开发python的unittest结果输出样式   Python的unittest结果命令行输出,格式比较乱.为了提高格式输出的可读性,实现可以不同的颜色标识.所以准备扩展Python的un ...

  6. java开发中经典的三大框架SSH

    首先我们要明白什么是框架为什么用?相信一开始学习编程的时候都会听到什么.什么框架之类的:首先框架是一个软件半成品,都会预先实现一些通用功能,使用框架直接应用这些通用功能而不用重新实现,所以大多数企业都 ...

  7. Java 9 尝鲜之JShell交互式编程环境

    JShell--Java 9 的交互式编程环境 本文要求读者有基本的 Java 知识. Tips Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容.也就是说,用 Java 9 写的代 ...

  8. css常用技巧集合

    1 不想让按钮touch时有蓝色的边框或半透明灰色遮罩(根据系统而定) /*解决方式一*/ -webkit-tap-highlight-color:rgba(0,0,0,0); -webkit-use ...

  9. 常见BOM实用对象

    1.跨浏览器获取窗口左边上边位置 2.IE9+.Chrome.Safari.Opera.Firefox支持下列属性. innerheight 返回浏览器窗口本身的高度. innerwidth  返回浏 ...

  10. git-ftp 用git管理ftp空间

    ftp管理不能实现版本控制,而且多电脑工作时,同步很成问题. git-ftp可以完美的解决问题 下面是我的趟坑之路,本机的环境是win10,首先你的机器得装有git. git-ftp的地址https: ...