Java集合

  1. Java集合概述

1)集合和数组都是对多个对象进行存储的作用(内存层面),它们都是一种容器。
2.1)数组在存储多个数据方面的特点:
》一旦初始化,长度就确定了
》数组一旦定义好,其元素类型也确定了,只能操作指定类型的数据。如 String[ ] arr, int [ ] arr1。
2.2)数组在存储多个数据方面的缺点:
》一旦初始化以后,其长度不可修改
》数组中提供的方法非常有限,对于添加、删除、插入数据等操作非常不便利。
》获取数组中实际元素的个数的需求,数组没有现成的属性、方法可用。
》数组存储数据的特点:有序、可重复,对于无序、不可重复需求,数组无法满足。

Java集合可分为Collection和Map两种体系
》Collection接口:单列数据,定义了存取一组对象的方法的集合
–List: 有序、可重复集合
–Set: 无序、不可重复集合
》Map接口:双列数据,保存具有映射关系的“Key-Value”对的集合。

  1. Collection接口方法

boolean add(E e)
boolean addAll(Collection<? extends E> c)
void clear()
int size()
boolean isEmpty()
boolean contains(Object o): 调用了equals()方法来比较
boolean containsAll(Collection<?> c):
boolean remove(Object o): 也是先调用equals()方法看是否包含
boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
boolean equals(Object c)
Object [ ] toArray();
int hashCode()
Iterator iterator()

  1. Iterator迭代器接口

集合元素的遍历。Iterator对象称为迭代器(设计模式的一种),为容器而生。
hasNext():指针不下移。
next():指针下移,并返回下移后指向的对象。
remove(): 删除当前游标指向的元素,不能删除两次。

while(iterator.hasNext()){
      System.out.println(iterator.next());
}

注意:a. 遍历时不能每次新造Iterator对象。 b. 每次调用next()方法,游标指针都会下移。

JDK5.0新增foreach循环也可遍历集合

for (Object obj : collection) {
    System.out.println(obj);
}

逐个将集合中的元素赋值给obj变量,直到遍历完成。内部也是使用迭代器实现的。

  1. Collection子接口:List
    三个实现类:ArrayList; LinkedList; Vector
    不同点
    ArrayList:作为List接口的主要实现类。线程不安全,效率高。底层使用Object [ ]。
    LinkedList:对于频繁的插入和删除操作,使用此类效率更高。其底层使用双向链表存储。
    Vector:古老实现类,基本已经很少用了。线程安全,效率低。

ArrayList源码分析。
JDK1.7:如果能预知大概长度,推荐使用带参构造器,防止扩容引起性能损失。
JDK1.8:调用add()方法时,才创建长度为10的数组,后续扩容与1.7无异。

E get(int index)
E set(int index, E element)
void add(int index, E element)
E remove(int index)
boolean remove(Object o)
int indexOf(Object o)
int lastIndexOf(Object o)
List subList(int fromIndex, int toIndex): 左闭右开区间。

  1. Collection子接口:Set

存储的数据无序、不可重复,有三个实现类:
HashSet:作为Set的主要实现类。线程不安全的,可以存储null值。底层是数组+链表的结构。
LinkedHashSet:是HashSet子类,增加了链表指针。遍历时可以按照元素添加的顺序进行。
TreeSet:使用二叉树(红黑树)存储。可以按照对象的指定属性排序。

Set接口没有定义新的方法,所有方法都来自Collection接口。
以HashSet为例,无序性不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是按照哈希值。
不可重复性:保证添加的元素按照equals()方法判断时,不能返回true,即相同的元素不能重复添加。

添加元素的过程,以HashSet为例
a. 计算元素的哈希值,该哈希值决定了它在数组中存放的位置。
b. 如果该位置已有元素,则比较哈希值是否相同,如不同,以链表方式将旧元素指向新元素
c. 如果哈希值也一样,则调用equals()方法判断是否为相同元素,如果不相同,则以链表方式将旧元素指向新元素

LinkedHashSet:在原有的HashSet基础上,每个数据还维护了两个变量,记录此数据的前一个和后一个数据。对于频繁的遍历操作,效率高于HashSet.

TreeSet:向TreeSet当中添加的数据,必须为同一个类的对象。两种排序方式自然排序和定制排序。在自然排序中,比较两个对象是否相同的标准为compareTo()方法返回0,不再是equals()。TreeSet不能放相同的数据,使用compareTo()比较的结果为准,只要返回0就认为是相同元素

  1. Map接口

HashMap:作为主要实现类;线程不安全,效率高;可以存储null值的key或者value.
|----LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序进行遍历。
TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此处是使用key的值进行排序的(自然排序或定制排序)。TreeMap底层使用红黑树存储。
Hashtable:作为古老的实现类;线程安全,效率低
|----Properties:常用来处理配置文件

HashMap的底层:JDK7.0是数组+链表,JDK8.0是数组+链表+红黑树。
Map中的key:无序的、不可重复的,使用Set存储所有的key ----> key所在的类要重写equals()和hashCode()
Map中的value:无序的、可重复的,使用Collection存储所有的value
一个键值对:key-value构成了一个Entry对象
Map中的entry:无序的、不可重复的,使用Set存储所有的Entry.

HashMap底层实现原理
JDK7:
HashMap map = new HashMap()
实例化以后,在底层创建了长度16的一维数组Entry [ ]
…可能执行若干次put()…
map.put(key1, value1);
首先调用key1所在类的hashCode()方法计算key1哈希值,此哈希值经过某种计算方法后,得到在Entry数组中存放的位置。
如果此位置数据为空,此时的key1-value1添加成功。—情况1
如果此位置上的数据不为空,比较当前key1和已存在数据的key值的哈希值。
如果哈希值都不相同,此时key1-value1添加成功。—情况2
如果key1和某个数据的哈希值相同,继续比较equals()方法
如果equals()返回false,此时key1-value1添加成功。—情况3
如果euqals()返回true,使用value1替换相同key的value值。(相当于put()方法具有修改value值的功能)

补充:关于情况2和3,此时key1-value1和原来的数据以链表的方式存储。
在不断的添加过成功,会涉及扩容问题,默认的扩容方式是扩容为原容量的2倍,并将原有的数据复制过来。

JDK8相较于7在底层实现方面的不同:

  1. new HashMap()的时候底层尚未创建长度为16的数组。
  2. JDK8底层数组是Node[ ], 而非Entry[ ]
  3. 首次调用put()方法是,底层才创建长度为16的数组。
  4. JDK7底层只有数组+链表,JDK8中底层为数组+链表+红黑树,当数组的某一个索引位置上的元素以链表形式存在的数据>8且当前数组长度>64,此时此索引位置上的所有数据改为使用红黑树存储。

Map常用方法
增删改操作:
V put(K key, V value):将key-value添加(或修改)到当前map对象中
void putAll(Map<? extends K, ? extendsV> m):将m中所有k-v对存放到当前map中
boolean remove(Object key):移除指定key的key-value对,并返回value值。
void clear(): 清除当前map中的所有数据
查询操作:
V get(Object key):获取指定key对应的value
boolean containsKey(Object key): 是否包含指定key
boolean containsValue(Object value): 是否包含指定value
int size(): 返回map中k-v对的个数
boolean isEmpty(): 判断当前map是否为空
boolean equals(Object o):判断当前map和参数对象o是否相等
元视图操作方法:
Set keySet(): 返回所有key构成的Set集合
Collection values():返回所有value构成的Collection集合
Set entrySet(): 返回所有key-value对构成的Set集合。

Properties: 用于处理配置文件

  1. Collections工具类
    Collections是操作Collection和Map的工具类。
    排序操作(均为static):
    reverse(List l): 反转list中的元素
    shuffle(List l): 随机排列list中的元素
    sort(List l): 自然排序
    sort(List l, Comparator c):定制排序
    swap(List l, int index, int index): 交换元素

Object max(Collection c)
Object max(Collection c, Comparator comp)
Object min(Collection c)
Object min(Collection c, Comparator comp)

int frequency(Collection c, Object o)
void copy(List dest, List src):注意dest.size()一开始是0,则复制的时候会抛出异常,应该按照src的size来指定dest的size。
boolean replaceAll(List list, Object oldVal, Object newVal):

Collections里面提供了多个synchronizedXxx()方法,将对应的集合转换为线程安全的。
List list1 = Collections.synchronizedList(list); //此时list1已经是线程安全的。

  1. 集合与数据结构相关
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值