一. 集合
1.什么是集合:
将多个对象集中整合在一个对象中,用来存储对象的容器,跟数组作用一样,很多时候替换掉数组。集合从大的方向分为两种,一种Collection接口,另一种是Map接口。
a. Collection接口的子接口包括:set接口,List接口。
b. Map接口的实现类主要有:HashMap,TreeMap,LinkedHashMap,Hashtable等。
c. Set接口的实现类主要有:HashSet,TreeSet,LinkedHashSet等。
d. List接口的实现类主要有:ArrayList,LinkedList,Stack以及Vector等。
2.它定义的位置:
java.util包中
3.集合和数组有什么区别
集合 | 数组 | |
---|---|---|
长度 | 可以变的 | 固定的 |
存储数据 | 可以是任意类型的 | 同一类型的数据 |
存储类型 | 只能存储引用类型的数据 | 可以存储基本数据类型,也可以存储引用数据类型 |
二.Collection接口
1.描述:
Collection是集合接口,一个Collection代表一组Object。下面有两个子接口List和Set
2.常用方法
方法名 | 作用 |
---|---|
add(Object obj) | 往集合中添加一个对象 |
clear() | 清空集合 |
contatins(Object o) | 判断集合中是否包含某个对象 |
isEmpty() | 判断当前集合是否为空 |
remove(Object o) | 将o对象从当前集合中移除(仅JavaSE用) |
size() | 获取集合中元素的个数 |
三.List接口
1.理解:
有序集合(也称序列),是Collection的子接口
2.特点:
有序,有下标,元素可以重复
3.下标范围:
0~size-1
4.常用方法:
方法名 | 作用 |
---|---|
add(int index,Object element) | 将元素添加到指定index位置(添加) |
get(int index) | 返回ndex位置的元素(查看) |
remove(int index) | 移除index位置的(删除) |
set(int index,Object element) | 更换index位置的元素(修改) |
注意: 如果指定下标超过下标范围,则运行报错。错误信息*java.lang.IndexOutOfBoundsException*
(下标越界异常)
5.遍历集合元素
a.使用for循环下标遍历:
for(int i=0;i<集合名.seize();i++){
//利用get方法配合下标获取元素
System.out.println(list.get());
}
例如:
List list=new ArrayList();
//遍历集合
for(int i=0;i<list.size();i++){
//利用get方法配合下标获取元素
Object obj=list.get(i);
}
b.forEach遍历
for(数据类型 变量名:要遍历的集合名){
//直接通过变量名操作元素
}
注意:()中的数据类型取决于集合中的泛型类型
例如:forEach遍历集合
List list=new ArrayList();
for(Object obj:list){
//每次循环从list数组中取出一个元素,自动为obj赋值
System.out.println(obj);
}
例如:forEach遍历数组
int[] a={1,2,3,4,5,6,};
for(int e:a){
//每次循环从a数组中取出一个元素自动为i变量赋值
System.out.println(e);
}3
c.迭代器的遍历
1理解
List接口从Collection接口中继承了Iterator()函数,返回值是一个List类型的迭代器(泛型)。
2常用方法
常用方法 | 作用 |
---|---|
next() | 返回迭代的下一个元素 |
remove() | 从底层集合中删除此迭代器返回的最后一个元素(可选操作)。 |
hasNext() | 如果迭代具有更多元素,则返回 true 。 |
3>
例如:
ArrayList<Student> str = new ArrayList<>();
for (Iterator<Student> it = str.iterator(); it.hasNext(); ) {
String next = it.next();
System.out.println(next);
it.remove();
}
6.实现类
ArrayList(常用) | LinkedList(少用) | Vector(几乎不用) | |
---|---|---|---|
底层实现 | 底层是通过数组实现的,通过索引下标可以快速的查到数据,所以它对数据的查询操作效率高的多。 创建集合对象时,底层数组长度为0,只有当第一次往集合中添加元素的时候,为数组分配空间,长度默认为10,如果存储的元素个数达到数组的长度上限时,自动扩容,每次扩容为原来的1.5倍。 | 底层使用双向链表实现的,因此它对于数据增删改查要比ArrayList要高。 | 通过数组来实现的,但是效率一般比ArrayList低,如果不考虑线程安全问题,一般使用ArrayList |
线程安全 | 不安全 | 不安全 | 安全 |
数据可重复 | 可以 | 可以 | 可以 |
特点 | 查询快,增删慢 | 增删块查询慢 | 线程安全 |
7.泛型接口
1描述
java1.5版本后引入泛型,泛型允许我们为集合提供一个可以容纳的对象类型,所以,添加其他类型会报错。这样可以保证数据类型的统一,代码的整洁,方便对集合中的数据统一管理,
2语法
ArrayList<数据类型> list=new ArrayList<>()
;
注意: 基本数据类型使用需要对应的包装类型作为泛型类型。
例:
//只能存储于Student对象。
ArrayList<Student> list=new ArrayList<>();
list.add(new Student() );
四.set接口
1.理解:
基于HashMap来实现的,是一个不允许有重复元素的集合,允许有null值。是Collection的子接口。
2.特点:
无序,无下标,元素不可以重复
3.常用方法:
方法名 | 作用 |
---|---|
add(Object o) | 添加元素 |
remove(Object o) | 删除元素 |
4.实现类
HashSet | LinkedHashSet | |
---|---|---|
底层实现 | 数组+链表,链表过长会转换为红黑树 | HashSet+双向链表 |
线程安全 | 线程不安全 | 线程不安全 |
5.简述HashSet验证方式(元素不可以重复)
a. 获取对象的HashCode,如果对象的HashCode不同HashSet认为不是重复对象;如果HashCode相同,HashSet认为对象有可能重复,再次调用equals进行确认。
b. 由于Object中的hashCode根据地址生成的HashCode,所以地址不同,HashSet就认为这是不同的对象,在程序中地址不同而属性相同,我们也认为对象是重复的。(解决方法:覆盖Object中的HashCode,根据属性生成一个HashCode)。
备注:
1.hashCode: 哈希码,Object中提供的方法,可以使用hashCode()方法获取一个对象的哈希码(Object中的hashCode是根据内存地址生成的一个int类型整数。)
2.hashCode生成原则: 每个不同的对象尽量不一样,相同的对象一样hashCode不仅决定了对象的存储位置,HashSet还要通过hashCode验证对象是否为重复对象
3. 使用HashSet时,如果存储自定义类型,务必覆盖hashCode于equals两个方法。
五.Map接口
1.Map集合
Map是一种按照键(key)存储元素的容器,键(key)就是下标,可以是任何类型的对象,Map中不能有重复的键,可以有重复的值,每个键都有一个对应的的值(value)。一个键(key)和它所对应的值(value)构成Map集合中的一个元素。
2.常见方法
方法名 | 作用 |
---|---|
put(K key,V value) | 向Map添加一组键值对,如果键已存在则覆盖 |
remove(K key) | 根据key删除一组键值对 |
size() | 获取Map集合中键值对的个数 |
get(k key) | 根据键获取对应的值 |
containsKey(Object key) | 判断key是否存在 |
containsValue(Object value) | 判断value是否存在 |
keySet() | 获取所有的键,返回值为Set |
values() | 获取所有的值,返回值为Collection |
entrySet() | 返回所有的entry(键值对),返回值为Set |
clear() | 清空 |
3.Map集合的遍历
1>.键遍历
Map<Integer,String> map=new HashMap<>();
//键遍历,获取所有的键
Set<Integer> keys=map.keySet();
//遍历keys获取每一个键
for(Integer key:keys){
//利用key获取value
String value=map.get(key);
System.out.println(value);
}
2>.值遍历
Map<Integer,String> map=new HashMap<>();
//获取所有的value
Collection<String> values=map.values();
//遍历
for(String value:values){
System.out.println(value);
}
3>.键值遍历
Map<Integer,String> map=new HashMap<>();
//获取所有的键值对
Set<Map.Entry<Integer,String>> entrys=map.entrySet();
//遍历set集合获取每个Map.Entry
for(Map.Entry<Integer,String> entry:entrys){
Integer key=entry.getKey();//获取key
String value=entry.getValue();//获取value
System.out.println(key+" -"+value)
}
4. HashMap实现类
1.HashMap底层存储原理
a. HashMap底层为数组(存储键值对),每次存储键值对,调用key对应对象的HashCode方法获取一个哈希值(整数),通过哈希码值%底层数组实际长度获取一个整数结果,为存储下标;当存储下标位置已经存在元素,此时调用key对应对象的equals方法,如果equals方法返回结果返回为true,则当前键值对会被拒绝添加到Map集合中。如果返回为false,则成功添加,此时采用数据+链表的形式进行存储。
b. 如果保证Map的键的内容不重复,需要覆盖HashCode和equals方法。
2.特点
键无序,唯一;值有序,可以重复,可以存储null的键和值
5.实现类
1,LinkedHashMap:
特点: 是HashMap的子类,可以按照键添加的顺序进行存储;操作速度块,线程不安全,可以维护元素的插入顺序
2.Hashtable:
特点: jdk1.0版本,线程安全,并发效率低,不允许null作为key/value;操作速度慢,线程安全。
6.HashMap和Hashtable的区别
HashMap | Hashtable | |
---|---|---|
线程安全 | 不安全,不同步 | 安全,同步 |
键或值 | 可以为空 | 不能为空 |
执行效率 | 效率高 | 效率低 |
底层 | 哈希表结构 | 哈希表结构 |
六.List/Set/Map集合的区别。
List | Set | Map | |
---|---|---|---|
特点 | 有序,有下标,可以重复 | 无序,无下标,不可以重复 | 无序,无下标,(key)不可以重复,(value)可以重复 |
存储结构 | 单列存储 | 单列存储 | 双列存储 |
接口实现 | 实现Collection父接口 | 实现Collection父接口 | 没有 |
实现类 | ArrayList;LinkedList;Vector; | HashSet;LinkedHashSet; | HashMap;HashTabale等; |