Java集合相关

集合

集合大致可分为双列集合和单列集合,单列集合为collection接口,双列集合为map接口
在这里插入图片描述

单列集合collection接口又分为list接口和set接口,map集合主要是hashmap
在这里插入图片描述

数组和集合的区别:

  • 集合是Java提供的一种容器,可以存放多个数据
  • 数组是定长的,集合是长度可变的
  • 数组可以存放基本数据类型,只能存放同一类型的元素,可以存放对象,集合只能存储对象

集合 的遍历方法:

利用toArray();方法,将集合转换为数组,然后遍历数组

    	    List list = new ArrayList<>();
            list.add("张三");
            list.add("李四");
    
            for (int i = 0; i < list.size(); i++) {
                Object[] array = list.toArray();
                System.out.println(array[i]);//张三、李四 
            }

使用迭代器iterator();返回可以进行迭代器进行迭代的方法

    		List list = new ArrayList<>();
            list.add("张三");
            list.add("李四");
    
            Iterator iterator = list.iterator();
            while (iterator.hasNext()){
                Object next = iterator.next();
                System.out.println(next);
            }

注意:
for循环分为两种,普通for循环和增强for循环,普通for循环就是基于索引的for循环,增强for循环是底层基于迭代器实现的,增强for循环能够遍历所有collection集合,普通for循环只能遍历有序的list集合,不能遍历无序的set集合。

collection集合

List集合

特点:存取有序,允许存储重复元素,有循环,可以使用for循环和迭代器(增强for循环)遍历;
list集合常用方法:
add(Object object):向集合中添加数据
get(int index):获取集合中指定的索引位置的元素数值
size():获取集合的长度
isEmpty():判断集合是否为空
contains(Object object);//判断结合中是否含有指定的这个元素
set(int index, Object object):更改集合中指定索引位置的元素数值
toArray():将集合转换为数组 返回值是一个数组,可以进行遍历
remove(int index):删除集合中指定索引位置的元素数值
clear():清空集合元素数值,谨慎使用

1.ArrayList(查询快增删慢)
ArrayList底层基于数组实现容量大小动态变化,由于ArrayList底层实现是数组,
所以查询效率高,增删效率低,线程不安全(因为正常使用是用来查询,不会涉及
太多的增删),涉及频繁增删的操作时就使用LinkedList,需要线程安全就使用
vector。

ArrayList扩容过程:是通过数组进行扩容的,ArrayList原始大小为10,当存储
数据大于10时,就会进行扩容,扩容具体步骤是,首先创建一个长度为15的数组,
然后将原长度为10的数组复制Arrays.copyOf到长度为15的数组中,地址长度变为
15,以此类推。

ArrayList增删慢的原因:添加数据或者删除数据都需要将原数组进行复制,再进
行增删操作,所以效率较低。

这里需要了解数据结构中的数组的特性,数组查询快的原因是数组在内存中的地址是
连续的,可以通过索引快速查找,增删慢的原因是数组的长度是固定的,每次增删都
需要创建新数组,然后复制源数据,原数组会在内存中被销毁(垃圾回收),地址也
会改变。

ArrayList遍历比LinkedList快的多,因为ArrayList在内存上的连续性,CPU
的内部缓存也会缓存结构连续的片段,可以大幅降低读取内存的性能开销。
2.LinkedList(查询慢增删快)
底层基于链表实现,在数据结构中,链表的特点为查询慢,增删快,查询慢原因是链
表中的地址是不连续的,每次查询都需要从头开始,增删快的原因是每个节点都有头
节点和尾节点,头节点和尾节点存放的是相邻数据的头节点和尾节点位置,当增删时,
只需要改变头尾节点的地址就可以。

set集合

特点:不允许存储重复元素,没有索引,无序集合,存取可能顺序不同

HashSet(不重复无索引无序):
  • 不允许重复元素
  • 没有索引,没有带索引的方法
  • 是一个无序集合,存储和取出元素的顺序可能不同
  • 底层是哈希表,查询速度非常快
  • 可用迭代器或增强for循环h获取里面的元素
LinkedHashSet:(有序不重复)
  • 继承了HashSet
  • 底层数据结构是哈希表(数组+链表/红黑树)+链表
  • 多余的一条链表是为了保证元素有序
  • 有序不允许重复
  • 是set集合中唯一一个能保证存取有序的集合对象
TreeSet(自排序不重复红黑树):
  • TreeSet是有序集合,不能有重复元素
  • 不按照插入顺序排序,可按照元素排序
  • 底层数据结构是红黑树,可以对元素进行排序
  • 对需要对自定义对象进行TreeSet排序,必须实现Comparable接口(implement Comparable),重写comparableTo()方法

Map集合

  • map集合是双列集合,通过键可以找到对应的值
  • map集合中的元素key和value的数据类型可以相同,可以不同
  • map集合的key不可以重复,value可以重复
  • map中的key和value是一一对应的,一个key对应一个value

map集合的遍历

keyset+迭代器遍历:

HashMap<String,Integer>map=new HashMap<>();
map.put("张飞",23);

map.put("关羽",33);
map.put("刘备",44);
Set<String>set=map.keySet();//使用keySet方法将HashMap集合中的元素存放到set集合中
Iterator<String>it=set.iterator();//使用set集合的遍历方法迭代器
while(it.hasNext()){
String key=it.next();
Integer value=map.get(key);
System.out.println(key+"="+value);
}

增强for循环遍历

for(Stringkey:set){
Integer value=map.get(key);
System.out.println(key+"="+value); 
}

map的key是唯一的,重写了hashcode和equals方法

HashMap

hashmap底层数据结构在1.8之前是数组加链表,在1.8时改进为数组加链表或数组加红黑树,当链表元素达到8后链表自动转换为红黑树,当再次小于8时,会回退为链表;hashmap的扩容机制在1.8之前是头插法,在1.8时改为尾插法,因为头插法在多线程的环境下扩容可能会造成链表死循环,比如两个线程的情况下第一个一个线程是A--》B,第二个线程是B--》A,在当容器不够的情况下,进行重写hash,可能形成环。
HashMap的put过程

hashmap的put过程,首先将需要插入的元素进行hashcode,通过字符串计算出ASCII码,然后以数组的长度进行mod运算,从而计算出哈希表中的下标位置。其中比较重要的几个参数为
Capacity :hashmap当前长度
LoadFactory :负载因子,默认值0.75

HashMap.size >=Capacity*LoadFactory时进行扩容

扩容步骤:

  • 创建新的entry空数组,长度为原来的二倍
  • reHash,遍历原Entry数组,把所有的Entry数组重新Hash到新数组(重新hash原因是长度改变后Hash规则也改变了)
HashMap的get过程
 	先以下标(index)查找链表的头部节点(数组),查到后查看hashcode是否
 	相等,不相等,查看next是否为空,直到查到hashcode相同为止,这就是
 	hashmap的get过程,遍历链表

在HashMap 的put过程和get过程中,只有put过程会产生线程安全问题,get过程不会产生线程安全问题

LinkedHashMap

类似于LinkedHashSet,是在HashMap基础上增加一条链表,保证存取有序

HashTable

HashTable就是线程安全的HashMap,就是在HashMap基础上增加了synchronized 关键字来确保线程安全,但是效率太低也被舍弃,需要线程安全的集合可用juc下的ConcurrentHashMap ,采用锁分段技术,底层采用CAS

TreeMap

该集合类似于TreeSet,底层数据结构是以红黑树实现的,特点就是可排序,TreeMap默认是按照key的自然排序排列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值