一.概念
-
一种储存多个对象容器,多数情况下可以替代数组
-
特点:便利操作数组,位于java.util包下
二.Collection
-
位置:java.util
-
特点:储存元素
-
方法:
add(Object obj);向集合中添加元素obj; remove(Object obj);从集合中删除元素obj; clear();删除集合中所有元素; size();返回集合中有效的元素个数; contains(Object obj);判断集合中是否包含元素obj; isEmpty();判断集合是否为空; toArray();将集合转为数组
-
结构图:
三.List
-
位置:Java.util(collection的子接口)
-
特点:有序、有下标、元素可重复
-
方法:
add(int index,Object obj);向index的位置添加元素obj; remove(int index);删除集合下标index处的值; set(int index,Object obj);将集合中下标index处的值跟换成obj; get(int index);返回集合下标index处的值;
-
实现类
-
ArrayList:开发应用重点
-
特点 :有序有下标、元素可重复、底层数组实现、查询快、增删慢,JDK1.2产物,线程不安全、效率高。
-
问题:new ArrayList();如何创建集合对象,集合容量是多少?扩容量是多少?
答:JDK1.7之后创建ArrayList集合初始容量为0的数组,开始添加元素,数组长度自动增长为10, 后期元素添加满数组后集合进行扩容,扩容长度是原数组的1.5倍。
-
-
LinkedList
- 特点:有序有下标、元素可重复、底层链表实现、查询慢、增删慢、线程不安全。
- 特点:有序有下标、元素可重复、底层链表实现、查询慢、增删慢、线程不安全。
-
Vector
-
特点:有序有下标、元素可重复、底层数组实现、查询快、增删慢、线程安全、效率低。
-
问题:ArrayList 、 LinkedList、Vector的区别?
答: 存储结构: 1.ArrayList和Vector是按照顺序将元素存储(从下标从0开始),删除元素时,删除操作完成后,需要使部分元素移位,默认的初始容量都是10 2.ArrayList和Vector是基于数组实现的,LinkedList是基于双向链表实现的(含有头结点) 线程安全性: 1.ArrayList不具有有线程安全性,在单线程的环境中,LinkedList也是线程不安全的,如果在并发环境下使用它们,可以用Collections类中的静态方法synchronizedList()对ArrayList和LinkedList进行调用即可 2.Vector实现线程安全的,即它大部分的方法都包含关键字synchronized,但是Vector的效率没有ArraykList和LinkedList高 增删改查的效率: 1.ArrayList 、Vector增删慢,删除集合其中一个元素后,会使其后面元素向前移动一位,LinkedList删除其中一个元素,直接把该元素的上个元素中储存的地址指向该元素的下个元素地址
-
-
-
遍历方式
-
通过下标进行遍历
for(int i=0;i<集合名.size();i++){ //通过get(i)获取集合元素 }
-
使用foreach进行集合遍历
for(泛型类型 o:集合名){ //o代表集合中的元素 }
-
迭代器遍历(foreach的原理)
//创建迭代器,在底层数组首元素之前生成指针 Iterator<泛型类型> i=集合名.iterator(); //hasNext():指针的下一个元素是否有值 //next():获取指针的下一个数据,获取之后指针向后移动一位 while(i.hasNext()){ //通过i.next()获取集合元素 }
-
forEach遍历
//Iterable接口中方法 collection继承Iterable接口 default void forEach(Consumer action) { for (Object o : this) { action.accept(o); } } Consumer接口 void accept(Object o); //需要定义Consumer的实现类 list.forEach(o->{可以通过o获取集合元素});
-
-
排序–JDK8.0
集合名.sort((o1,o2)->{//o1为后者,o2为前者 负数换位置 正数不换位置 //指定排序规则 return 整数; });
四.泛型集合
-
泛型集合:类型安全的集合,强制要求集合中的数据类型保持一致
-
语法:
List<元素的数据类型> list = new ArrayLIst<元素的数据类型>(); 注意: 在集合中只允许添加泛型类型的数据 进行集合遍历时,直接取值泛型类型,不需强转 =右边泛型可以不用添加,添加<>,有系统默认添加泛型 泛型没有多态,前后泛型类型保持一致
-
泛型类
class 类名<泛型>{}
-
泛型接口
interface 接口名<泛型>{}
-
泛型方法
public static<泛型> void 方法名(A a){}
五.Set
-
特点:无序无下标、元素不可重复
-
方法:继承collection的方法
add(Object obj);向集合中添加元素obj; remove(Object obj);从集合中删除元素obj; clear();删除集合中所有元素; size();返回集合中有效的元素个数; contains(Object obj);判断集合中是否包含元素obj; isEmpty();判断集合是否为空; toArray();将集合转为数组
-
实现类
-
HashSet:开发应用重点
-
特点:无序无下标、元素不可重复,底层哈希表实现
-
问题:HashSet如何保证元素不重复?
答:比较元素内容是否相同,使用equals(),为了避免equals(),多次执行,使用hashCode()触发equals()执行。 hashCode()返回的哈希码值相同,进行内容对比,返回true,不添加 hashCode()返回的哈希码值不同,不再执行equals(),直接添加 重写HashCode方法:使用字面值的哈希值之和(基本类型直接使用字面值)
Hashset如何添加一个元素?什么是散列函数?HashSet添加元素时如何散列?什么时哈希?
答:当添加元素时,先计算对象的哈希码值,对数组长度取余,余数为元素插入的数组下标,如果该位置为null,直接添加; 数组中已经添加有元素,先进行哈希码值比较,如果哈希码值不同,直接拉链存储,如果哈希码值相同,调用equals()进行内容比较,内容相同舍弃当前对象,如果不同,拉链存储 JDK1.8以后,如果桶上长度超过8,转为红黑树存储,目的提高查询效率 加载因子是0.75,扩容时机当数组的容量达到总长度75%开始进行扩容,扩容长度为当前的一倍
-
-
LinkedHashSet:
- 特点:可以记录插入顺序的set集合,底层由哈希表+链表实现
-
TreeSet:
- 特点:可以排序的集合
- 位置:Collection–>Set—>SortedSet—>TreeSet
-
-
遍历方式
- 迭代器遍历
- forEach遍历
- foreach遍历
六.Map
-
位置:java.util
-
特点:键值对存储,键不可重复,值可以重复
-
方法:
put(Object k,Object v);向集合中添加键值对 remove(Object k);通过键删除键值对 coear();清空集合 get(Object k);通过键获取值 size();返回集合中有效元素的个数 containsKey(Object k);判断集合中是否包含k键 containsValue(Object v);判断集合中是否包含v值 isEmpty();判断集合是否为空 values();返回所有值的Collection集合 keySet();返回所有键的Set集合 entrySet();返回所有键值对的Set集合
-
实现类
-
HashMap:开发应用重点
-
特点:键值对存储,键不可以重复,值可以重复,底层哈希表实现,允许null键和null值,线程不安全,效率高
-
问题:HashMap如何存值
答:new HashMap();在内存开辟数组,数组长度为16 当添加元素时,先计算对象键的哈希码值,对数组长度取余,余数为元素插入的数组下标,若该位置为null,直接添加; 若该位置以及有元素,先进行哈希码值比较,如果哈希码值不同,直接拉链储存; 如果哈希码值相同,调用equals()进行键内容比较,键内容相同覆盖原有值,如果键内容不同,拉链存储 JDK1.8以后,如果桶上长度超过8,转为红黑树存储,目的提高查询效率 加载因子是0.75;扩容时机是数组容量达到总长度的75%开始扩容,扩容长度为当前的一倍
-
-
Hashtable:
- 特点:键值对存储,键不可以重复,值可以重复,底层哈希表实现,不允许null键和null值 ,线程安全,效率低;
-
LinkedHashMap(有序的Map):
- 特点:可以记录插入顺序map集合,底层哈希表+链表
- 位置:Map–>HashMap–>LinkedHashMap
-
Properties:
- 特点:键值都是字符串
- 位置:Map–>Hashtable–>Properties
- 作用:读取流中的数据
-
TreeMap(有序的Map):
-
特点:可以通过键排序的Map集合
-
位置:Map–>SortedMap–>TreeMap
-
问题:HashMap和Hashtable的区别?
答: 安全性: HashMap线程不安全,HashTable线程安全 是否允许null值: HashMap允许null值和null键,HashTable不允许null值和null键 计算hash值方式不同: Hashtable直接使用key对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数法来获得最终的位置 HashMap为了得到元素的位置,首先需要根据元素的 Key计算出一个hash值,然后再用这个hash值来计算得到最终的位置
-
-
-
遍历方式:
-
键遍历
Set<Integer> set = map.keySet(); set.forEach(o->{ //o是键 通过键获取值get(o) });
-
值遍历
Collection<String> c = map.values(); for(String s:c) { //通过s获取所有值 }
-
键值对遍历
Set<Map.Entry<Integer,String>> set1=map.entrySet(); for(Map.Entry<Integer, String> e:set1) { //通过getKey获取键 //通过getValue获取值 }
-
forEach遍历
map.forEach((k,v)->{ //k为键 为值 });
-
-
结构图
看完如果对你有帮助,感谢点赞支持!