Java中提供给程序开发使用处理数据结构的一种方式。
数组的局限性太大了!!!
1. 数组要求数据类型一致化!!!
2. 数组的容量确定之后无法更改!!!
3. 数组操作没有太多的配套方法,需要程序员自己完成!!!
集合解决的问题:
1. 可以满足多个数据类型,但是同时又做到了数据类型一致化操作【泛型】
2. 底层保存数据的容量是可以发生改变的
3. 有足够多的配套方法,可以满足最基本的增删改查操作 CRUD
集合可以看作是一种容器,用来存储对象信息。所有集合类都在 java.util 包下,但支持多线程的集合类位于 java.util.concurrent 包下。Java的集合类主要由两个根接口派生出来,分别是Collection 和 Map
<1>Collection
List:实现了collection接口,list可以重复,有顺序
实现方式:3种,分别为:ArrayList,LinkedList,Vector。
1、【ArrayList】底层是一个动态数组,数组是使用连续的内存空间,有索引,所以它查询快,增删的时候需要移动内存,所以增删慢。
2、【LinkedList】底层是一个动态链表,内存是不连续的,查询的时候需要一个节点一个节点的找,所以说,查询慢,但是增删快,因为他不需要挪动内存,只需要修改链表指针。
ArrayList和LinkedList都是**线程不安全,线程不同步的。**的,所以适合于单线程。
3、【Vector】也实现动态数组,已经被ArrayList替代,它是属于查询安修改也慢,他可以无限加长,是线程安全的,因为它底层用synchronize修饰。
Stack是Vector的实现类,实现一个后进先出的堆栈。
Stack提供5个额外的方法使 Vector得以被当做堆栈使用。push 和 pop 方法,还有 peek 方法得到堆栈的元素, empty方法测试堆栈是否为空,search 方法检测一个元素在堆栈中的位置。Stack 刚创建后是空栈。
4、队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
Deque类是Queue的实现类。而LinkedList 类既实现了 List 接口又实现了 Deque 接口(也就实现了 Queue接口)。Queue 接口窄化了对 LinkedList 的方法的访问权限,即在方法中的参数类型如果是 Queue 时,就完全只能访问 Queue 接口定义的方法了,而不能直接访问 LinkedList 的非 Queue 的方法。以使得只有恰当的方法才可以使用。
Set:实现了collection接口,不可重复,也没有顺序
实现方式:HashSet,TreeSet,
1、【HashSet】,底层数据结构是哈希表,存取和查找性能好。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素
LinkedHashSet是 HashSet 的一个子类,具有 HashSet 的特性。
底层数据结构是链表和哈希表,由链表维护元素有序,元素的顺序与添加顺序一致。由哈希表保证元素唯一。
2、【TreeSet】:底层数据结构是二叉树,是 SortedSet 接口的实现类,可以保证元素处于排序状态。对排序有更高的要求时使用。
<2>Map
Map接口采用键值对 Map<k,v> 的存储方式,保存具有映射关系的数据。因此,Map 集合里保存两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 可以是任意类型的数据,key 值不允许重复,可以为null。如果添加 key-value 对时 Map中已经有重复的 key,则新添加的value 会覆盖原来对应的 value。
1、【HashTable与HashSet】
HashTable 与 HashSet 是 Map 接口的两个典型实现,他们之间的关系完全类似于 ArrayList 和 Vertor.HashTable 是一个古老的Map实现类,它提供的方法比较繁琐,目前基本不用。
特点:
HashSet线程不安全,线程不同步,HashTable 线程安全,线程同步。
HashMap 效率高,通常比 HashTable 要快。因为HashTable比较古老。
HashMap的key与value可以是null值。HashTable不允许使用Null值作为key和value,如果把null放入HashTable中,会发生空指针异常。
2、【LinkedHashMap】类
LinkedHashMap基于Map接口的哈希表和链接列表实现,有序由哈希表保证键的唯一性,使用双向链表维护 key-value对的次序(其实只需要考虑key的次序即可),该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。
3、Properties类
Properties类时Hashtable类的子类,它相当于一个key、value都是String类型的Map,主要用于读取配置文件。
4、TreeMap类
TreeMap是SortedMap的实现类,是一个二叉树的数据结构,每个key-value对作为二叉树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap也有两种排序方式:
自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则会抛出ClassCastException。
定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。
线程安全:多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,
进行保护其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出
现数据不一致或者数据污染。线程不安全就是不提供数据访问保护,有可能出现
多个线程先后更改数据造成所得到的数据是脏数据。通常来说,是在访问临界资
源的代码前面加上一个锁,当访问完临界资源后释放锁,让其他线程继续访问。
线程同步:线程有时候回和其他线程共享一些资源,比如内存、数据库等。当
多个线程同时读写同一份共享资源的时候,可能会发生冲突。这时候,我们就
需要引入线程“同步”机制,即各位线程之间要有顺序使用,不能杂乱无章随意
使用。
在Java中,提供了两种方式来实现同步互斥访问:synchronized和Lock。
线程安全主要有3种解决办法:
方法1: Collections.synchronizedList(new LinkedList())
方法2: LinkedList和ArrayList换成线程安全的集合,如CopyOnWriteArrayList,ConcurrentLinkedQueue…(写时复制技术,并发读,独立写,写完合并)
方法3:Vector(内部主要使用synchronized关键字实现同步)
参考链接:
线程安全,为什么说ArrayList,LinkedList是线程不安全的,以及CopyOnWriteArrayList和vector为什么安全
HashMap,Hashset,ArrayList以及LinkedList集合的区别和用法