一. 集合框架:
1. collection接口:单列集合,用来存储一个一个的对象;collection接口主要有两个子接口:list子接口、set子接口
① List子接口:存储有序的、可重复的数据。 ------>相当于“动态”数组,主要的实现类有ArrayList、LinkedList、Vector;
注:向List中添加数据,其数据所在的类要重写equals()方法
问题:ArrayList、LinkedList、Vector三者的异同:
同:三个类都实现了List接口,都是存储有序的、可重复的数据。
不同之处:ArrayList :作为List接口的主要实现类,线程不安全,执行效率高,底层使用Object[ ]存储,默认长度为10
LinkedList:对于频繁的插入和删除操作,使用效率比ArrayList高,底层使用双向链表存储
Vector:作为List的古老实现类,执行效率低,线程安全
ArrayList扩容: 当使用无参构造时,默认长度是0;add()添加元素时,如果长度<10,则扩容长度为10,如果长度>10,则按照当前长度的1.5倍进行扩容
② Set子接口:存储无序的、不重复的数据,类似高中数学的“集合”;主要的实现类有HashSet、LinkedHashSet、Treeset;
注:向Set中添加数据,其所在的类一定要重写hashCode()和equals()。
HashSet :作为Set接口的主要实现类,是线程不安全的,可以存储null值;
向HashSet中添加元素的过程:当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来 得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象在 HashSet 底层数组中的存储位置。(这个散列函数会与底层数组的长度(默认为16)相计算得到在数组中的下标,并且这种散列函数计算还尽可能保证能均匀存储元素,越是散列分布,该散列函数设计的越好)如果两个元素的hashCode()值相等,会再继续调用equals方法,如 果equals方法结果为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了,那么会通过链表的方式继续链接。
LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历;
TreeSet:可以按照添加对象的指定顺序,进行排序。向TreeSet添加的对象,要是相同类型。
2. Map接口:双列集合,用来存储一对一对(key-value)的数据,一个key-value构成一个entry。相当于Python的字典;主要实现类有HashMap、LinkedHashMap(是HashMap的子类)、TreeMap、HashTable、Properties(是HashTable的子类)。
① HashMap:Map的主要实现类,使用频率最高,线程不安全的,效率高;可以存储null的key和value。所有的key构成的集合是Set:无序的、不可重复的。所以,key所在的类要重写equals()和hashCode();所有的value构成的集合是无序的、可重复的。所以,value所在的类要重写equals()。HashMap 判断两个 key 相等的标准是:两个 key 通过 equals() 方法返回 true,
hashCode 值也相等。HashMap 判断两个 value 相等的标准是:两个 value 通过 equals() 方法返回 true。
重要:HashMap存储原理:jdk7.0及以前:向HashMap中添加entry1(key,value),需要首先计算entry1中key的哈希值(根据key所在类的hashCode()计算得到),此哈希值经过处理以后,得到在底层Entry[]数组中要存储的位置i。如果位置i上没有元素,则entry1直接添加成功。如果位置i上已经存在entry2(或还有链表存在的entry3,entry4),则需要通过循环的方法,依次比较entry1中和其他entry的key。如果彼此hash值不同,则直接添加成功。如果hash值相同,继续比较二者是否equals。如果返回值为true,则使用entry1的value去替换equals为true的entry的value。如果遍历一遍以后,发现所有的equals返回都为false,则entry1仍可添加成功。
jdk8.0以后的修改:1. entry改成了Node[];2. 当数组某一位置上的元素以链表形式存在的个数>8 且 当前数组长度>64时,此索引位置上的所有数据改为红黑树存储
LinkedHashMap:是HashMap的子类,保证在遍历map元素时,可以按照添加的顺序实现遍历。原因:在原有的hashmap底层结构基础上,添加了一对指针,指向前一个和后一个元素。对于频繁的遍历操作,此类执行效率高于HashMap
② TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序
③ Hashtable:古老的实现类;线程安全,效率低;不能存储null的key和value;
Properties:Hashtable的子类,常用来处理配置文件
二. 迭代器接口:
Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。
注:① Iterator 仅用于遍历集合(即collection,不用于遍历Map),Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
②.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
@Test
public void test1(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("tom"));
coll.add(false);
Iterator iterator = coll.iterator();//返回一个实现了Iterator接口的对象
//常用于遍历集合
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
迭代器接口的remove()方法:
@Test
public void test2() {
Collection coll2 = new ArrayList();
coll2.add(123);
coll2.add(456);
coll2.add(new String("tom"));
coll2.add(false);
Iterator iter = coll2.iterator();
while(iter.hasNext()) {
Object obj = iter.next();
if("tom".equals(obj)) {
iter.remove();
}
}
System.out.println(coll2);
}
注意:①. Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
②. 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报异常。
for-each可以遍历集合或数组。
Collection接口常用方法:
1、添加
add(Object obj)
addAll(Collection coll)
2、获取有效元素的个数
int size()
3、清空集合
void clear()
4、是否是空集合
boolean isEmpty()
5、是否包含某个元素
boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
boolean containsAll(Collection c):也是调用元素的equals方法来比
较的。拿两个集合的元素挨个比较。
6、删除
boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
boolean removeAll(Collection coll):取当前集合的差集
7、取两个集合的交集
boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
8、集合是否相等
boolean equals(Object obj)
9、转成对象数组
Object[] toArray()
10、获取集合对象的哈希值
hashCode()
11、遍历
iterator():返回迭代器对象,用于集合遍历
List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法:
void add(int index, Object ele): 在index 位置插入ele 元素
boolean addAll(int index, Collection eles): 从index 位置开始将eles中的所有元素添加进来
Object get(int index): 获取指定index 位置的元素
int indexOf(Object obj): 返回obj 在集合中首次出现的位置
int lastIndexOf(Object obj): 返回obj 在当前集合中末次出现的位置
Object remove(int index): 移除指定index 位置的元素,并返回此元素
Object set(int index, Object ele): 设置指定index 位置的元素为ele
List subList(int fromIndex, int toIndex): 返回从fromIndex 到toIndex位置的子集合
Map接口的常用方法:
一. 添加、删除、修改操作 :
1. Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
2. void putAll(Map m):将m中的所有key-value对存放到当前map中
3. Object remove(Object key):移除指定key的key-value对,并返回value
4. void clear():清空当前map中的所有数据
二. 元素查询的操作:
5. Object get(Object key):获取指定key对应的value
6. boolean containsKey(Object key):是否包含指定的key
7. boolean containsValue(Object value):是否包含指定的value
8. int size():返回map中key-value对的个数
9. boolean isEmpty():判断当前map是否为空
10. boolean equals(Object obj):判断当前map和参数对象obj是否相等
三. 元视图操作的方法:
11. Set keySet():返回所有key构成的Set集合
12. Collection values():返回所有value构成的Collection集合
13. Set entrySet():返回所有key-value对构成的Set集合