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. [python爬虫]爬取学校教务处成绩

    学校教务处网站 登陆窗口 表单数据 观察登陆窗口和提交的表单数据可知只要将账号.密码.验证码正确赋值提交即可模拟登陆. 账号和密码都有,问题的关键就在验证码上. 右键验证码图片审查观察源码如下图: 刚 ...

  2. 开源一个vue2的tree组件

    一直打算偷懒使用个现成的树组件,但是在github上找了一大圈没有找到真正满足应用开发的树组件,所以没办法只能自己写了一个,开源出来希望可以帮助到需要的人,同时如果大家觉得好用,我可以顺带骗骗★(希望 ...

  3. Web前端面试指导(十四):如何居中一个元素(正常、绝对定位、浮动元素)?

    题目点评 这道题目的提问比较多,连续问了三个问题,正常元素.绝对定位元素.互动元素如何居中,而且居中没有说清楚是垂直居中还是水平居中,要回答清楚这个问题,必须得有深厚的功底,而且要分类的来回答,条理要 ...

  4. 填坑实录 Android Studio 利用 ADB WIFI 插件实现真机无线调试

    总是用模拟器,小破本的渣内存无法承受,同时模拟器的版本大多停在4.4,无法体现Android 5.0.6.0 的版本特性,因此决定利用 Android Studio 的插件实现真机无线调试. 步骤如下 ...

  5. Luogu1074靶形数独【启发式搜索】

    Luogu1074靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, ...

  6. 【Egret】Lakeshore 使用中的一些疑难解决技巧!

    用Lakeshore 1.2.1版本发布的html,会出现一些用户不想要的东西,下面讲讲如何去掉: 一.问题:游戏或者动画在PC端也能跟随游览器自适应. 解决方法:①找到发布文件下的  egret_l ...

  7. 2.Redis的基本配置

    一.参数配置 redis.conf的主要配置参数的意义: daemonize:是否以后台daemon方式运行 pidfile:pid文件位置 port:监听的端口号 timeout:请求超时时间 lo ...

  8. 什么是javascript的回调函数?

    回调函数(callback) 基本上每本书里都会提一提实际上我们几乎每天都在用回调函数,那么如果问你到底什么是回调函数呢? 1. 回调函数是作为参数传递给另一个函数 2. 函数运行到某种程度时,执行回 ...

  9. iOS实现高斯模糊效果(Swift版本)

    给UIimage添加分类 extension UIImage { /// 高斯模糊 func gaussianBlur(var blurAmount:CGFloat) -> UIImage { ...

  10. redis object 对象系统

    redis object对象系统 概述 redis 当中, sds字符串, adlist双向链表, dict字典, ziplist压缩链表, intset整数集合等均为底层数据结构 redis 并没有 ...