看尚硅谷视频做的笔记
1.集合框架概述
1.1生活中的容器
首先知道集合是来解决什么问题的?
1.1.1内存层面需要针对于多个数据进行存储,此时,可以考虑的容器有:数组、集合类
对于内存层面的来说,断电后数据就不复存在,内存层面的数据都是一些临时性处理的数据。跟数据库的数据不是一个维度。
就相当于数据是先从数据库读到内存中,数据库的数据可以用数组去存、也可以用集合去存储。
1.2 数组的特点、弊端
1.2.1数组存储多个数据方面的特点
①数组一旦初始化,长度就确定了。
②存储的数据有相关特点:依次紧密排列,并且是有序、可重复的
③优点:数组一旦初始化完成,其元素的的类型就是确定的,不是此类型的元素,就不能添加到此数组中。
声明int类型,就只能是int类型,声明是String类型,就只能是String类型
int [ ] arr=new int[10];
arr[0]=1;
arr[1]=‘AA’//编译报错;
想体现更灵活的用户,就声明为Object类型数组
Object obj=new Object[];
obj[0]=‘AA’;
obj[1]=1;
obj[2]=new String();
obj[3]=new Date();
④优点:元素的类型即可以是基本数据类型,也可以引用数据类型。
集合中的元素存放只能是基本数据类型,不能是引用数据类型。若你集合中有基本类型的需求那只能用包装类的对象往里放,就只能放对象特征。
对集合来讲,其实对类型没有什么要求,可以随便往里放数据类型。不会对类型进行检查,这样就会使得容器里的东西比较杂,不安全,怎么办?下一章会讲1泛型,性新特性。泛型就专门限制往集合里放的类型。
泛型类型,写的是String,就只往里放String,其他类型就放不进去。
泛型就可以达到跟数组一样的特征。
1.2.2数组存储多个数据方面的弊端
①数组一旦初始化,长度就不可变了。
数组new的时候在堆空间是一整块空间
1和1就可以看成是可以重复的
②数组中存储数据特点的单一性、对于无序、不可重复的常见的多个数据就无能为力了
③数组中可用的方法、属性都极少,具体的需求,都需要自己组织相关的代码逻辑。
④针对于数组中的元素的删除、插入操作、性能较差,原因是因为:存储的数据、依次紧密排列,
1.3Java集合框架体系
这章整体是从接口体系出发的
像之前讲异常体系都是从类出发threable \errable\exception
比较典型的接口有两个:
1.3.1 java.util.Collection接口:存储一个一个的数据
①------List子接口:有序可以重复的数据
List子接口下面具体的实现类:ArrayList(主要的实现类)、LinkedList、Vector
②------Set子接口:无序不可重复的数据
Set子接口下面具体的实现类:HashSet(主要的实现类)、LinkedHashSet、TreeSet
1.3.2 java.util.Map接口:存储一对一对的数据(key-value,一个key对应一个value,键值对数据)
一个x1对应一个y1,一个x2对应一个y2,综合就相当于是函数y=f(x)
Map会有针对于key、value的要求,不同的key可以指向同一个value,一个key不能指向多个value
y=x ^2
x=-1,x=1,y=1
Map这里也是一样,不同key可以指向同一个value,同一个key不能指向多个value
跟Collection并列的接口Map,Map没有子接口
①直接提供的具体的实现类HashMap(主要的实现类)、LinkedHashMap、TreeMap、Hashtable、Properties
HashSet的底层就是HashMap
LinkedHashSet的底层是LinkedHashMap
TreeSet的底层是TreeMap
1.3.3怎么理解List存储有序可以重复的数据?
List跟前面的数组有些类似:称为动态数组,可以动态扩展底层数组的长度。
其实List就可以替换以前的数组,具体用的话就是实现类,ArrayList是作为主要的实现类
我们要做的就是具体的实现类是谁,怎么创建对象?怎么用常用的方法完成项目的需求
1.4集合的使用场景
1.4.1无序不可重复的使用场景:黑名单、手机骚扰电话拦截
黑名单其实就是一个Set集合,加进黑名单后,就没有必要再加一份
红色圈住的都是可以理解为对象,这里面就有多个对象,多个对象就考虑容器去装,上下是有顺序讲究,以前是数组,现在可以用集合List实现类,ArrayList去装数据即可
这一项可以用对象去封装数据,也可以不用对象去封装,可以用一个Map容器
Map容器是一个键值对
下面圈住的红色结构
里面都是key,key可以理解成一个标签
key在这里是image,imagepath对应的是url地址,即就是键值
多个Map构成List
安卓或者pc客户端发送请求到服务端,服务端可以用java代码去编写逻辑,java可以去访问数据库
数据库返回的是数据是结果集给java层面的代码最后再响应给客户端即就是看到的页面数据
本质上页面的数据都是来自数据库,java的作用就是根据用户的个性化请求访问数据库返回给客户端,在服务器的层面写的都是java代码,针对于数据可以使用List、Map进行去装数据,至于返回到客户端是什么样的格式,暂时不多说。
1.5学习的程度把握
1.5.1 层次一:针对于具体特点的多个数据,知道选择相应的适合的接口主要实现类,会实例化,会调用常用的方法。
1.5.2 层次二:区分接口中不同的实现类的区别
1.5.3 层次三:①针对于常用的实现类,需要熟悉底层源码。②熟悉常见的数据结构(第14章讲)
后面就先讲Collection,再讲Map
2.collection接口及方法
jdk8里有一些默认的方法,更多的是体现的是一种规范,规范更多关注的是一些抽象方法。
看接口里面的抽象方法,选一个具体的实现类。
测试collection的方法,存储一个一个数据都有哪些功能方法可以进行调。
因为是接口,想演示接口中的方法,就需要先声明Collection
右边一定要选一个实现类,即就用ArrayList
此处就使用了多态
多态
场景时调的时候.
coll.时候只能调出Collection接口里面声明的方法
所以借着右边ArrayList看左边Collection接口的方法
具体执行还是右边ArrayList中的方法,那右边执行方法就等于左边Collection方法吗?(虽然接口中的方法么没有方法体,方法的用途是确定的,所以此处不影响去理解Collection接口中的方法)
COllection用ctrl+c,再打开API
在jdk8加了静态方法和默认方法,现在暂时不关注,后面String的Api再关注
现在关注的都是抽象方法,15个抽象方法
如果自己设计一个Collection,去存储一个一个的数据,会设计哪些方法?
2.1 添加
2.1.1add(E obj)添加元素对象到当前集合中,一个一个添加元素
123基本数据类型,此处是自动装箱操作
造一个自定义类的对象Person
提供name,age,再提供空参构造器
再提供带参构造器
get,set方法省略,提供toString方法
new一个Tom
以上就添加了5个对象
此处打印的时候里面也调了toString方法d
就将对象打印了出来
2.1.2addAll(Collection other):添加other集合中的所有元素对象到当前集合中,即this=this U other
(将参数中的元素都加到当前集合中coll)
新建coll1
对coll1加点数据,加完后进行调用addAll方法,再进行打印
在原有的数据上又加了两个数据,原先是5个元素,现在加了两个数据后是7个元素
size获取集合中元素个数的方法
2.1.3注意:add和addAll的区别
coll.add是将coll1集合看成是整体的一个元素
此时再查询集合元素的个数就是6
整个coll1集合中的元素充当了一个元素
2.2判断
2.2.1 int size()获取当前集合中实际存储的元素个数
2.2.2 boolean isEmpty()获取当前集合中是否为空集合
判断集合是否为空,false
2.2.3 boolean contains(Object obj)判断当前集合中是否存在一个与obj对象equals返回true的元素
判断是否包含AA
返回值为true
coll.contains(128),返回的结果为true
coll.contains(128)此处是自动装箱,128此处已经超出了数组的范围,这就是新new的,
这个包含的128是新new的,此处比较的不是==,不是比地址,
举例说一下,此处new的是一个String
判断是否包含,此处返回也是true,比较的不是地址,而是比较的是内容
调的是equals方法,String和Integer都重写过,即都是true
此处这样是true
此处运行返回后,是false
System.out.println(coll.contains(new Person(“Tom”,12)));此处按理说调的还是equals方法-再去看Person类的代码,Person类的代码里没有重写equals方法,用的是Object里的equals方法就是==,进行地址比较
这两个地址相比显然不一样,即就是false
一般调contains时都是调的是equals方法,就是比内容,对于自定义对象的这种想往集合里放元素,都要求在自定义类中重写equals方法alt+insert
hashcode代码用不着可以进行注释
可以发现调用了几次
调用了四次
contains若添加的是自定义的类的对象,就需要在自定义类中加上重写的equals方法
2.2.4 boolean containsAll(Object obj)判断coll集合中的元素是否在当前集合中都存在,即coll集合中的元素是否在集合中的子集。
2.2.5 boolean equals(Object obj):判断当前集合与obj是否相等
2.3删除
2.3.1 void clear():从当前集合中删除第一个找到的与obj对象equals返回true的元素
打印size为0,不是空指针的原因是test3方法里有Collection p1=new ArrayList()对象
clear方法的原理
Collection p1=new ArrayList(),ArrayList集合底层也是数组
此处只能是放对象,都是Object,此处都是放的地址值(因为是引用类型)
地址值再指向new的对象
一个一个进行清理掉(而不是size为0,防止内存泄漏)
2.3.2 boolean remove(Object obj):删除指定元素。从当前集合中删除所有与coll集合中相同的元素,即this=this-this交集 coll
此处new一个person,能否删掉
此处删掉了,删的话判断有新new的对象就会进行删除,判断有没有时调的是equals方法(肯定有啊),有就会进行删除,remove是一旦找到了想要删除的元素就会停止进行操作
2.3.3 boolean removeAll(Collection coll):删除集合中的所有元素。从当前集合中删除两个集合中不同的元素,使得当前集合仅留与coll集合中的元素相同的元素,即当前集合中仅保留两个集合的交集。即this=this交集 coll
coll.removeAll(coll1)删除coll1所有元素
差集的意思
2.3.4boolean retainAll(Collection coll):从当前集合中仅保留与coll集合中的元素相同的元素、即当前集合中仅保留两个集合的交集,即this=this交集coll
即是交集
2.4其他
2.4.1Object[] toArray():返回包含当前集合中所有元素的数组,集合—>数组
先整一个集合过来
集合怎么转换成数组
返回值是用Object类型数组进行装(因为添加的时候都是Object)
看一下数组具体的元素都有哪些?此处有一个简便的方法
这就是数组中的元素
2.4.2hashcode[]:获取集合对象的哈希值
2.4.2iterator:返回迭代器对象,用于集合遍历
2.5总结
2.5.1.常用方法:Collection中定义了15个抽象方法
add(Obj obj)
addAll(Collection coll)
size()
isEmpty()
contains(Object obj)
cotainsAll(Collection coll)
retainAll(Collection coll)
hashCode()
remove(Object obj)
removeAll(Collecion coll)
clear()
Iterator()
toArray()
2.5.1.集合与数组之间的相互转换
2.5.1.1 集合---->数组:toArray()方法,返回类型是一个Object类型的数组Object[]
2.5.1.2 数组---->集合:调用Arrays的静态方法asList(Object …obj)
数组转集合,首先要有数组,数组有一个工具类Arrays
Arrays有一个方法asList(T…a),形参是一个可变形参,此处就可以放可变数组
假设有一个数组arr,形参就是arr数组
返回值就是一个集合
alt+回车自动生成返回类型
泛型暂时没见过,先删除
List是Collection的子接口,即就是collection
即就转换成了collection
打印list
这种写法也是可以的
2.5.1.3 注意
① 场景1
此处有一个小细节,此时的代码是自动装箱
此处有多少个元素?
② 场景2
问下面的size是多少?
asList只能放对象,不能放基本数据类型,只能将整个数组看成是一个对象,即就是一个元素,而对于Integer他是自动装箱后的对象
打印一下list、list1的元素的情况
第二个[[I@1888ff2c]是int类型的一维数组
2.5.1.向Collection中添加元素的要求:要求元素所属的类一定要重写equals方法
因为调contains或者remove方法时,他要去调obj所属类的equals方法,调equals比较的是内容,若不重写的话会去调用Object中的==不太合适