集合那点事
什么是集合?
集合可以看作是一个容器,如红色的衣服可以看作是一个集合,所有Java类的书也可以看作是一个集合。
java.util 包中提供了一些集合类,这些集合类又被称为容器。
数组和集合的区别:
- 数组的长度是固定的,集合的长度是可变的
- 数组用来存放基本数据类型,集合用来存放对象的引用。
- 数组只能存储相同类型的数据,集合可以存储不同类型的数据。
常用集合类的继承关系

Collection接口
| 方法 | 功能描述 |
| size() | 返回集合中元素的个数(集合的长度) |
| add(Object o) | 添加元素 |
| addAll(Collection c) | 把集合c里面所有的元素添加到当前集合中 |
| isEmpty() | 判断当前集合是否为空,如果为空就为true |
| clear() | 清空集合中的元素 |
| contains(Object o) | 判断当前集合中是否包含指定元素o |
| containsAll(Collection c) | 判断集合c中所有的元素是否都存在于当前集合中 |
| remove(Object o) | 删除集合中的元素o |
| removeAll(Collection c) | 从当前集合中删除另一个集合c所有的元素 |
| toArray() | 将集合转成一个数组 |
| equals() | 判断两个集合的元素值是否相等 |
| hashCode() | 返回是当前对象的哈希值 |
Collections和collection的区别?
Collections 是一个操作 Set、List 和 Map 等集合的工具类
collection是set和list的一个父接口
排序操作:(均为static方法)
- reverse(List):反转 List 中元素的顺序
- shuffle(List):对 List 集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
- sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
- swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
- Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
- Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
- Object min(Collection)
- Object min(Collection,Comparator)
- int frequency(Collection,Object):返回指定集合中指定元素的出现次数
- void copy(List dest,List src):将src中的内容复制到dest中
- boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
List集合
List 集合包括List 接口以及List 接口 的所有实现类。List集合存储的数据是有序的,是可以重复的。List集合中的元素允许重复,各元素的顺序就是对象插入的顺序
List继承Collection,所以Collection中的方法,在list中也能用
除此之外,List还定义了两个非常重要的方法
1. get(int index) 获得指定索引位置的元素
2. set(int index,Object obj) 将集合中指定索引位置的对象修改为指定的对象
List接口的实现类有ArrayList和LinkedList以及Vector
ArrayList和LinkedList以及Vector的异同
相同点:
- 都是list 集合的实现类
- 存储数据的特点相同:有序的、可重复的
不同点:
- ArrayList类实现了可变的数组,允许保存所有元素,包括null,并可以根据索引位置对集合进行快速的随机访问,缺点是向指定的索引位置插入对象或删除对象的速度较慢。
- LinkedList类采用链表结构保存对象。便于向集合中插入和删除元素,效率比ArrayList高,但是对于随机访问,效率则比ArrayList低。
- Vector:是list接口的古老实现类,线程安全的,效率比较低
ArrayList底层实现
List list=new ArrayList(); //并且对数组 Object[] elementData进行了初始化,初始化为{}
list.add(1);
//第一次调用add方法,底层对数组长度进行了指定,指定为10,如果添加的新元素导致数组elementData容量不够,则进行了扩容,扩容了1.5倍,同时将原数组的元素值复制到了扩容后的新数组里面
LinkedList底层实现
List list=new LinkedList():在内部声明了Node类型的first和last属性值,默认为null
list.add(1); //调用add方法,把1封装到node中,创建了Node对象
node的定义为:
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
Vector底层实现
在调用无参构造方法Vector()的时候,底层创建了一个长度为10的数组,它扩容的是2倍
Set集合
Set接口中的对象是无序的,是不能重复的,Set接口继承Collection接口
Set接口常用的实现类有HashSet与TreeSet
HashSet:由哈希表支持,不保证Set的迭代顺序,允许使用null
LinkedHashSet:是HashSet的子类,遍历内部数据的时候,可以按照添加的顺序进行遍历,LinkedHashSet效率要高于HashSet
TreeSet:不仅实现了Set接口,还实现了SortedSet接口,因此顺序是递增的
TreeSet新增方法:
1. first() 第一个元素,或者是最低的元素
2. last() 最后一个元素,或者最高的元素
3. comparator() 返回对此Set中的元素进行排序的比较器,如果是自然顺序,则返回null
4. headSet(E toElement) 返回一个新的集合,新集合是toElement(不包含)之前的所有对象
5. subSet(E fromElement,E fromElement) 截取集合并返回一个新的集合,包含前不包含尾
6. tailSet(E fromElement) 返回一个新的集合,新集合是fromElement(包含)之后的所有对象
HashSet实现原理
1.我们向HashSet里面添加元素a的时候,首先调用元素a所在类的hasCode方法,计算元素a的哈希值,
计算出哈希值以后通过一些算法计算在HashSet底层在数组中存放的位置,判断数组的此位置有没有元素,
如果没有,直接把元素a添加到该位置(重写后hascode相同元素的哈希是一样的)
2.如果此位置有其他元素b,则比较两个元素的值是否相等(equals),
如果相等,元素a添加不成功
如果不相等,通过链条的方式把元素a添加的元素B的后面
Map集合
什么是Map集合,其结构是怎样的
Map集合提供的是key到value的映射,Map中不能包含相同的key,每个key只能映射一个value
Map中的key:无序、不可重复、使用set存储的
Map中value:无序、可重复的,使用collection进行存储的
key和value的组合就是一个Entry对象
Entry:无序的、不可重复的,使用set进行存储的
Map接口中的常用方法:
- put(K key, V value) 添加
- containsKey() 是否包含指定key的映射关系
- containsValue() 是否包含指定Value的映射关系
- get(key) 获取指定key的值,如果没有就返回null
- keySet 所有key形成的Set集合
- values 所有values形成的Collection集合
- clear() 清除
map的实现类
HashMap:map的主要实现类,线程不安全,效率高,存储null的key和value
-- LinkedHashMap:HashMap的子类,保证在变量map元素的时候,按照添加的顺序进行输出元素值
原因:在HashMap这个类的基础上,添加了一对指针,指向上一个元素的引用地址和下一个元素的引用地址,遍历效率比HashMap高
TreeMap:可以保证key-value进行排序,有序的输出,(自然排序和自定义排序)
Hashtable:古老的实现,线程安全的,效率低,不能存储null的key和value
--Properties:用来处理配置文件,jdbc
HashMap的底层实现?
Map map=new HashMap();对加载因子进行了初始化
map.put(123,123):首次调用put方法的时候,创建了一个长度为16的Node[]数组,并且对临界值进行了初始化为12
添加一个元素put(key1,value1),调用key1所在类的hashcode方法,计算key1的哈希值,对哈希值通过一些算法进行计算,得key1元素的位置,拿着这个位置去Node[]数组里面去找位置,
如果此位置数据为空,key1,value1添加成功。
如果此位置上的元素不为空,如果key1的哈希值和已经存在的一个数据(key2-value)哈希值不相同,直接添加成功。
如果key1的哈希值和已经存在的一个数据(key2-value)哈希值相同,调用key1的equals方法和key2进行比较:
如果equals比较的结果返回false,此key1,value1添加成功(已链条的形式存在)
如果equals比较的结果返回true,使用value1替换value2的值
jdk1.8hashMap地址结构:数组+链条+红黑树 当数组的某一个索引的位置上的元素以链条的形式纯在的数据个数>8 并且数组的长度>64的时候,此位置变成了红黑树 进行存储数据
遍历集合的三种方式
Collection<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
//1.迭代器
Iterator<String> iterator = list.iterator(); //创建迭代器
while (iterator.hasNext()){
String str = (String) iterator.next(); //iterator.next()返回的是Object对象,要强行转换成String
System.out.println(str);
}
//2. 增强for循环
for(Object o: list){
System.out.println(o);
}
//3.把集合转成数组,遍历数组
Object[] objects=list.toArray();
for(Object o:objects){
System.out.println(o);
}
遍历List集合的三种方式
List list=new ArrayList();
//1.添加元素
list.add("aaa");
list.add("bbb");
list.add(123);
list.add("bbb");
System.out.println("=============1.迭代器");
Iterator i=list.iterator();
while(i.hasNext()){
System.out.println(i.next());
}
System.out.println("=============2.增强for");
for(Object o:list){
System.out.println(o);
}
System.out.println("=====3.for循环");
for(int a=0;a<list.size();a++){
System.out.println(list.get(a));
}
遍历Map的两种方式
public void test(){ Map map=new HashMap(); map.put("1001","阿轲"); map.put("1002","韩信"); map.put("1003","李白"); map.put("1004","百里玄策"); //keySet():获取所有的key Set set=map.keySet(); for (Object o:set){ System.out.println(o); } System.out.println("=================="); //values():获取所有的value值 Collection values=map.values(); Iterator i=values.iterator(); while (i.hasNext()){ System.out.println(i.next()); } System.out.println("=================="); //key-value:通过一个循环获取key和value值 //遍历map的第一种方法 Set set1=map.keySet(); for (Object key:set1){ //根据key获取对应的value值 Object value=map.get(key); System.out.println(key+"-"+value); } System.out.println("================="); //遍历map的第二种方式 Set set2= map.entrySet();//获取所有的entry(key+value的组合) //从set集合里面取出每一个entry for(Object objs:set2){ //把父类转成子类 Entry entry=(Entry)objs; //获取对应的key Object key=entry.getKey(); //获取对应的value Object value=entry.getValue(); System.out.println(key+"-"+value); }
}

浙公网安备 33010602011771号