Java 集合框架

集合框架

集合

基本概念:
处理多个相同数据我们采用数组,但数组的空间固定不能动态增长,插入或删除元素比较复杂,我们就使用集合来解决。
特点:
1、元素类型可以不同、集合长度可变、空间不固定。
2、提供多个集合,不同的算法,采用合适的集合框架可以提高开发效率。
集合框架:
在这里插入图片描述

Collection

Collection是一个接口,不提供直接的实现,listset这两个子接口都继承与Collection,代表一种规则,它包含的元素必须遵循一条或多条规则。比如:有些允许数据重复,有些不允许数据重复,有些数据有顺序、有些没顺序。
在实际开发中,一般不能使用Collection来开发,使用它的子接口来进行开发。

List

List也是接口,是Collection子接口,List代表的是有序的CollectionList采用某种特定的插入顺序来保证里面的数据都是有顺序,用户可以对List中存放的数据根据位置来进行精确的控制,同时可以根据元素的索引来获取到元素的内容。
特点:
1、List中元素是由顺序。
2、List中允许元素的重复出现。
3、List可以支持null数据。
4、可以根据索引来获取List中的元素。

ArrayList

ArrayList是一个动态数组,最常见的集合,它允许任何符合规则的元素插入,包括null也能够插入。也可以说是一个可以进行动态扩容的数组,底层默认初始化的容量为10,该容量代表数组的大小,随着集合中的元素内容不断增加,容器的大小也随着变化,没想容器中加入数据时都要去检测当前容量是否够使用,当快要溢出时,进行增加容量的大小,但是这样扩容的效率比较低。
扩容:创建一个新数组,将以前的数据复制到新数组,旧数组消失。

// 创建ArrayList,默认大小为10
List list = new ArrayList();
// 添加元素
list.add(2);
list.add("jack");
list.add(13.4);
list.add(1, "pony")  // 在下标为1的位置,插入一个元素
// 获取元素
list.get(0); // 2类型为Integer自动装箱
// 删除元素
list.remove(0) // 删除下标为2的元素
list.remove(object obj); // 根据地址删除,不能传具体值
// 集合中是否有某元素
list.contanins(Object o);
// 修改指定位置的元素
list.set(1,"robin");
// 集合的长度
list.size()
LinkedList

ArrayListLinkedList都是实现List接口,ArrayList是一个动态数组,底层是一个双向链表,LinkedList除了有ArrayList的一些方法以为,提供额外的一些方法,通过一些方操作链表的头和尾。
由于两种集合底层数据结构不同,LinkedList不能随机访问,所有的操作都是按照双向列表来执行,在列表中索引会采用从头或者结尾来遍历数据,这样做的目的是在操作集合时删除、增加提高效率。
双向列表:
列表中的每个元素都是独立的,每个空间都存放本身的数据,以及上一个对象的引用和下个对象的引用(索引)。

// 创建LinkedList
List list = new LinkedList();
// 添加元素
list.add(3); // 3 类型为Integer自动装箱
list.add("jobs");
list.add(16.7);
list.add(1,8) // 在 下标为1的位置 添加8
list.add(Object o);
// 获取元素
list.get(2) // 获取下标为2的元素
list.getFirst() // 获取第一个元素
list.getLast()  // 获取最后个元素
// 修改元素
list.set(1, 10);
// 删除
list.remove(2) // 删除下标为2的元素
list.remove() // 删除此列表的第一个元素
Vector

ArrayList很相似,底层都是动态数组,但是Vector是线程同步的,在操作数据的方法上面加上了synchronized关键字线程安全的,jdk1.0 就有Vector,jdk1.2后才提出集合框架,很多程序还是用Vector来完成的,为了向后兼容,将Vector放在List下面,保留以前的Vector的特性,现在用ArrayList。 效率比ArrayList

// 创建对象
List list = new Vector();
list.add("Q") // 同步
各自优缺点

1、ArrayList底层是一个动态数组,LinkedList底层是双向链表来实现的。
2、对于随机访问,get、set ArrayListLinkedList的效率高,因为ArrayList底层是一个动态数组,查找元素在一个连续的空间栈速度快,LinkedList移动指针(索引)去判断当前元素下一个是否是我们需要的。
3、ArrayList结构对于数据的增删效率比较低,中间插入一个元素,以后的所有元素都要挪到位置,LinkedList前一个元素只需改变引用,后一个只需改变引用
4、Vector线程安全的,效率低下。
5、ArrayList扩容的效率比较低,你提前确定空间,需要时初始构造器数组容量。
源码解析:
当你调用add方法的时候,检查数组是否够用,如果不够,就创建一个大一倍的容量,将元你来的数组拷贝到新数组中,在将原来的数据废弃。
当调用remove()方法时候,将指定元素移除数组,将后面的元素整体向前移动,System.CopyOf()来实现,一次删除会有多个元素移动,add添加的时候,添加到指定位置整体向后移动。
LinkedList:
单链表: 单链表中链表对象维护一个first引用,该引用指向节点链表的第一个节点元素,每个节点对象维护了一个next引用,next指向下个元素引用。(节点对象:自己的数据,下一个元素的引用指向node())
双链表:链表对象维护了first引用和last引用,分别指向链表的首和尾,每个节点对象维护了当前对象的数据,prevnext引用,用来指向前后节点对象。

泛型

在集合中存放数据的时候可以存放任何类型的对象,底层是一个Object,取出来的数据默认也是Object对象,如果要将当前对象转化为要使用到的对象必须知道是什么类型的。
泛型在定义时指定了参数类型,这个参数默认用E(element)来表示元素,类型参数值是在声明变量或者创建对象时候确定。
当个集合指定泛型时,那就意味着操作内容就必须传递指定的参数类型,在获取集合元素时就不必再转化对象,默认返回类型就是传递的泛型类型。

List<String> lists = new ArrayList<String>();
lists.add("jack");
String name = lists.get(0);
// 如果不知道类型也可这样定义
// ? 占位符 根据在运行时确定类型
public List<?> listArray; 

Set

继承Collection
特点:
1、set存放的元素内容不能重复。当添加一个元素进入容器中时,要比较元素的内容是否重复,如果重复自动去掉重复的内容,如果比较的是对象,比较对象是否一致,需要重写hashcode()equals()方法。
2、存放的容器中的元素可以有顺序,也可以没顺序。
3、元素在容器中没有顺序,所有不能通过下标进行获取里面的数据。

hashSet

基于hash算法实现。
1、set元素不能重复
2、不能使用getset随机访问
3、元素没有顺序
4、元素允许null

// 创建
Set set = new HashSet();
// 添加元素
set.add(1);
set.add(2);
set.add(1);
// 获取
for (Object object : set) {
	System.out.println(object);  // 1, 2
}
// 判断是否存在
set.contains(2); // 存在 true ,反之False

将对象存放在set集合中,对象的引用一样,则去掉重复的对象。
hashSet集合中存放,会调用对象的hashcode()equals()方法比较对象是否一致,如果一样则不会被存放。
判断两个对象是否相等:
1、set会判断两个对象的hashcode码是否一致(hashcode一旦确定,元素在内存中的位置也将确定下来),如果两个对象hashcode码不一致,两个对象不相等。
2、如果hashcode码相等,然后在调用对象的equals()方法来比较值是否相等。如果值相等,才能确定这两个对象相等。
hashSet的数据结构:
jdk1.8之前,采用的hash表= 数组 + 链表
jdk1.8后:hash表= 数组 + 链表 || 数组 + 红黑树 (查询的速度快)
当产生hash冲突时(hash值一样,内容却不同),值就会用链表来存,但链表长度超过8的时候,自动会变成红黑数来排序。

TreeSet

1、可以允许排序的一种集合,继承SortSet接口
2、元素无法重复
3、底层是基于TreeMap来实现的,基于红黑树算法。Treeset的数据来源于TreeMapkey值,采用自然排序或自定义排序。

// 创建
TreeSet set = new TreeSet();
// 添加
set.add(2);
set.add(3);
set.add(4);
// 取第一个
set.first()
// 取最后一个
set.last();

特点:
在存储数据的时候,存放的数据时数值或字符串(本身有排序),按照默认排序。当存放的数据是自定义对象时,需要在存放对象类中实现Comparable,重写CompareTo()方法实现自定义排序。
Comparable称为比较器,常用于集合框架中。

迭代器

iterator 接口我们称为迭代器,用于遍历集合的一种接口。
遍历:从集合中取出每一个元素的过程,在Collection中有一个对象iterator对象,通过这个对象可以遍历集合中所有元素。

// 所有集合类都可以使用迭代器来完成数据的获取,
// 通过调研iteator获取到迭代器接口对象,返回迭代器泛型,值根据集合泛型来指定
// next() 来获取元素
Iteator<String> it = set.iterator();
String res = it.next();
Collections

Collections: 集合工具包,用于操作Collection所定义各种集合,所有方法都是静态方法。
Collection: 接口,集合的顶层框架,主要用于制定集合的规范。

Map接口

Map 接口用于维护键/值对(key/value pairs)。并没有继承Collection
特点:
1、key - value 有一一对应的关系,一个key对应一个唯一的值
2、在Map中不允许出现重复的键(key)值(value)可以一样。
3、HashMapTreeMap
4、将Map所有的key放在一起那就是Set集合,key可能有顺序,也可以没顺序。
5、把Map所有的值放在一起,就变成了一个Collection

Map map = new HashMap();
//在没有定义泛型时,键可以是任何类型,值也是任何类型
map.put("id", 6);
map.put("name", "jack");
map.put("money", 2600);
// 获取
int res = (Integer)map.get("id");
String res1 = (String)map.get("name");
// 获取所有键
Set set = map.keySet();
for (Obejct object : set) {
}
// 获取所有值
Collection conn = map.value();
Iterator it = conn.iterator();
while(it.hasNext()) {
	Object object = it.next();
}

属性:
initialCapacity: 初始容量,指的是hashmap在初始化的时候自身的容量。可以在构造方法中传递进来,如果不指定值,默认16。
size:当前hashMap的键值对数
loadFactor(DEFAULT_LOAD_FACTOR):当hashMap的值达到一定的范围后,我们就开始扩容,加载因子默认为0.75。
threshold:扩容阈值 一般默认扩容为原来的2倍,扩容阈值 = hashMap总量 * 加载因子。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值