java集合框架概述

集合框架类图
在这里插入图片描述

框架类图各接口及类

1. Iterator接口
迭代器(Iterator)是一个对象,它的工作是遍历并选择序列中的对象。它提供了一种访问一个容器(container)对象中的各个元素,而又不必暴露该对象内部细节的方法。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。

使用示例:

public class IteratorDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list .add("aaa");
        list .add("bbb");
        list .add("ccc");
        System.out.println("Before: " + list);
        Iterator<String> iterator = list.iterator();
        while (iterator .hasNext()) {
            String t = iterator .next();
            if ("bbb".equals(t)) {
                iterator .remove();
            }
        }
        System.out.println("After: " + iterator);
    }
} 

 输出:

Before : [aaa, bbb, ccc]
After : [aaa, ccc] 

注意:

  • Iterator只能单向移动。
  • Iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次next()方法,remove()方法只能被调用一次,如果违反这个规则将抛出一个异常。

1.1. ListIterator接口
 ListIterator是一个功能更加强大的迭代器, 它继承于Iterator接口,只能用于List类型的访问。并包含其他的功能,如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处。

使用示例:

public class ListIteratorDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list .add("aaa");
        list .add("bbb");
        list .add("ccc");
        System.out.println("Before: " + list);
        Iterator<String> iterator = list.iterator();
        while (iterator .hasNext()) {
        	System.out.println(iterator .next() + ", " + iterator .previousIndex() + ", "+ iterator .nextIndex());
        }
        while (iterator .hasPrevious()) {
            System.out.println(iterator .previous() + " ");
        }
        iterator = list.listIterator(1);
        while (iterator .hasNext()) {
            String t = iterator.next();
            System.out.println(t);
            if ("ccc".equals(t)) {
                iterator.set("nnn");
            } else {
                iterator.add("kkk");
            }
        }
        System.out.println("After: " + list);
    }
} 

 输出:

Before : [aaa, bbb, ccc]
aaa, 0, 1
bbb, 1, 2
ccc, 2, 3
ccc bbb aaa 
bbb
ccc
After : [aaa, bbb, kkk, nnn]

注意:

  • 与Iterator只能单向移动不同,ListIterator双向移动(向前/向后遍历)。

2. Collection接口
 Collection接口是处理对象集合的根接口,它包含了集合的基本操作和属性。Collection包含了List和Set两大分支。注意Map不是Collection的子接口。
在这里插入图片描述
 其中,有几个比较常用的方法,如方法add()添加一个元素到集合中,addAll()将指定集合中的所有元素添加到集合中,contains()方法检测集合中是否包含指定的元素,toArray()方法返回一个表示集合的数组。另外,Collection中有一个iterator()函数,它的作用是返回一个Iterator接口。通常,我们通过Iterator迭代器来遍历集合

2.1 List接口
 List接口继承于Collection接口。代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。
 实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

2.1 .1 ArrayList
 继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。同时还实现了 RandomAccess、Cloneable、Serializable 接口,所以ArrayList 是支持快速访问、复制、序列化的。
 ArrayList是非同步的

2.1 .2 LinkedList
 实现List接口的LinkedList与ArrayList不同,ArrayList 是基于数组实现的,遍历时很快,但是插入、删除时都需要移动后面的元素,效率略差些。而LinkedList 是基于双向链表实现的,插入、删除时只需要改变前后两个节点指针指向即可。
 LinkedList是非同步的

2.1 .3 Vector
 与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

2.1 .4 Stack
 Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

总结:
 ArrayList:数组结构,线程不安全,查找速度快,增加、删除速度慢。
 LinkedList:链表结构,线程不安全,查找速度慢,增加、删除速度快。
 Vector:数组结构,线程安全,已被ArrayList取代。
 Stack:继承Vector。

2.2 Set接口
 Set接口继承于Collection接口。它的特点是“无序、无索引、不可存储重复元素”;与List一样,它同样允许null的存在但是仅有一个。
 实现List接口的集合主要有:HashSet、LinkedHashSet、TreeSet。

2.2 .1 HashSet
 HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个哈希set,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。
 HashSet的实现方式,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象。

2.2 .2 LinkedHashSet
 LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

2.2 .3 TreeSet
 TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。

3. Map接口
 Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。
 实现Map接口的集合主要有:HashMap、LinkedHashMap、TreeMap。

3.1 HashMap
 HashMap基于hash原理,通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
 相对于JDK1.7,java8HashMap处理hash冲突时,会首先存放在链表中去,但是一旦链表中的数据较多之后,就会转用红黑树来进行存储,首先判断链表长度是否>8, 如果大于8但是数组长度小于64就扩容,否则就转红黑树(链表长度>8,且数组length>=64),优化存储速度。

3.2 LinkedHashMap
 LinkedHashMap是HashMap的一个子类,非同步,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。
 LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。可以分为:按插入顺序的链表,和按访问顺序(调用get方法)的链表。默认是按插入顺序排序,如果指定按访问顺序排序,那么调用get方法后,会将这次访问的元素移至链表尾部,不断访问可以形成按访问顺序排序的链表。由于LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能,但在迭代访问Map里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。

3.3 TreeMap
 TreeMap 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。

自然排序:TreeMap中所有的key必须实现Comparable接口,并且所有的key都应该是同一个类的对象,否则会报ClassCastException异常。

定制排序:定义TreeMap时,创建一个comparator对象,该对象对所有的treeMap中所有的key值进行排序,采用定制排序的时候不需要TreeMap中所有的key必须实现Comparable接口。

3.4 Hashtable
  Hashtable底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个Hashtable,效率比HashMap低。
 线程安全的HashMap,由于锁粒度大。已被ConcurrentHashMap取代。
:是Hashtable不是HashTable(T不是大写)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值