包装类
1、之前说过的把基本数据类型包装成面向对象的形式就是包装类
2、下面是包装类的一些特性和功能
正则表达式
1、正则表达式就是字符串变量要matches的规则,可以用xx.matches(正则表达式)来得到我们的字符串变量是否满足某种规则,具体的规则定义如下。
这些个规则具体可以去看java官方的api文档
2、除了用matches匹配判断是否满足某种规则,正则表达式还可以有下面几种用法
正则表达式同时还经常搭配pattern和matcher类使用,具体看文档
肯定还有很多其他的用法,具体方法api去看官方文档,要学会看文档
Arrays类--也是一个常用工具类
1、就是一个用来操作数据的类,之前也见过,比如里面的toString能快速打印数组内容成字符串
2、除此以外还有sort,binarySearch等功能,用法就是Arrays.sort(数组a)
3、sort还可以用Comparator自定义排序的规则,具体用到的时候自己看文档
Lambda表达式
匿名内部类回顾
1、把匿名内部类写法更简化的一种写法!
2、回顾一下什么是匿名内部类,匿名内部类本来就是一种简化的写法,是对一些接口,或者抽象类进行实例化的时候,直接用{}把方法重写了。例如:Animal a = new Animal(){xxxx把方法重写了}。相当于创建了一个没有名字的子类,继承了抽象类或者实现了接口。
3、然后要注意这里实际上实例化的是我们的匿名内部类的对象,而不是Animal的对象!这和多态的思想是不同的,一开始想错了,并不相当于多态。匿名内部类new出来的是当前new的那个类型的子类型!!!
Lambda表达式介绍
1、使用条件:Lambda只能简化接口中,只有一个抽象方法,的匿名内部类形式。 首先必须是接口,其次只有一个抽象方法,可以在接口前加一个@Functionalinterface会自动帮检验。
2、例如下面的代码
interface Swimming{
void swim() // 只有一个抽象方法的接口,接口方法自动public abstract
}
/*--------主函数部分----------*/
Swimming s1 = new Swimming(){ //正常匿名内部类的写法
public void swim(){
xxxxx // 重写抽象方法
}
}
Swimming s1 = () -> { // Lambda表达式的写法
xxxxx // 重写抽象方法
}
3、Lambda表达式可以直接用在方法中,即当方法需要某种类或接口的参数的时候,可以直接在传参那里写一个Lambda表达式,注意以后要能读懂这种写法。
4、参数类型可以不写! 相当于在python里见到的那种,直接写一个参数 ->方法表达式的写法,就相当于直接返回表达式内容的值。
书上对Lambda表达式的另一种介绍--一定要看书!
1、上面是课中介绍的Lambda表达式是对匿名内部类的简化,这里书上提供了另一种角度来介绍,更像是我之前看到的python中Lambda表达式的介绍。
2、Java是面向对象的语言,我们想在传一个代码块做方法参数的时候,不能直接传,我们要先定义一个类,然后构造一个对象,对象的类中写好所需要的代码。而这时就有了Lambda表达式来做到支持类似函数式的写法。
3、在JAVA中有很多专门用来封装代码块的接口,这种接口只有一种方法,方法里就写了某种规则,然后在调用某些方法如Sort方法时,可以加一个comparator接口作为参数,来指定排序规则。而这类接口就叫函数式接口,而Lambda表达式正可以等同于这种接口,相当于直接在传参的时候,就不需要new一个匿名对象,再把对象里的抽象方法重写,而是直接把Lambda表达式作为参数传进去就行。
如上两种写法是一个意思,而Lambda表达式就更简便!
O1,O2在比较器中是用来指代传入的对象的!!
集合
Collection--单列
1、Collection是一种接口,下面还有具体的其他子接口继承它和实现类实现子接口,如下图。
2、用构造器初始化的时候可以用多态的写法,可以调用collection的一些通用api。但是!!多态写法不能用子类的独有功能!!
Collection<String> list = new ArrayList();
Collection集合的一些遍历方式
1、迭代器遍历
2、增强for循环遍历(也可以遍历数组)
3、结合Lambda表达式遍历的API
forEach方法结合Lambda表达式
原理上是forEach里面加上一个Consumer接口,但是其实这就是一个函数接口,只有一个抽象方法,所以可以直接用lamba表达式来写!!!
4、不支持以索引进行遍历,因为collection中包含着set系列是不含索引的
List系列集合
1、List系列集合的遍历方式,除了上面说的三种还有一种就是for循环用索引来遍历!
2、对于List集合来说,存在集合并发修改异常问题,就是说当你边遍历边删除list内部元素时,可能会出错,因为你在遍历时把对象删除,会导致list索引变化,那么在遍历时就会漏掉元素,会报错。对于迭代器遍历,可以用迭代器.remove来删除,不会出错。对于for循环,可以自减,保证不出错,或者for循环可以倒着删,也不会出错。剩下两个没办法。
ArrayList集合底层原理及特点
实现上还是基于数组,当size等于当前数组长度时,会自动进行扩容
LinkedList集合底层原理及特点
像栈和队列这些数据结构就可以用LinkedList实现,涉及首尾操作,效率高
Set系列集合
HashSet底层原理
这里重点理解一下思想,HashSet怎么实现的,用到了数组,链表,哈希表思想还有红黑树的内容。
HashSet去除重复底层原理和修正
1、去重的原理可以见上一部分HashSet的原理思想,先判断hashcode对应的地址,再用eqauls判断内容。
2、但是默认是两个new的对象不是重复的,即使他们内容相同,因为他们的hashcode不同,且地址也不同。所以必须在对应的类中重写overridding两个方法:hashCode()和equals()方法,才能使得内容相同的对象有一样的hashcode,且equals返回True。这个IDEA可以自动生成。
LinkedHashSet特点及原理
TreeSet特点及原理
1、在定义类的时候,就实现Comparable比较器接口,重写一个比较规则的方法。
2、用TreeSet自带的比较器对象来制定规则,就是在new的时候在括号里再new一个comparator,然后重写compare方法来指定规则。其实就是new一个匿名对象,然后重写方法。
3、其实comparator就是一个函数接口,上面这种方法其实更简化的写法就是直接在new的括号里加一个Lambda表达式来指定规则就行。
3、在写规则时,浮点型可以直接用Double.compare()
Collections集合工具类
1、这只是一个工具类,Collection是我们的单列集合接口,collections是定义的一个工具类,里面存了一些操作单列集合collection的方法,注意区分!具体使用查看文档!
2、工具类里面提供了许多静态方法,就直接用类名调用即可!这种写法其实很常见,比如前面也有一个是object是一个究极父类,同时objects是对应的一个工具类,里面提供了很多重写后的静态方法,供object子类使用,但是其实因为所有类都继承至object,所以大家都可以用objects里的api。
Map集合!!
Map集合的一些常用API
Map集合的遍历方式
1、键找值
用上面说的KeySet()找出所有键,再用get()通过键去找值。先获得所有key再去找value。
2、键值对
把key-value当成一个整体,先把Map集合转成Set集合,Set集合每个元素都是键值对。然后去遍历Set。
3、结合Lambda表达式的API
原理上是forEach里面加上一个BiConsumer接口,但是其实这就是一个函数接口,只有一个抽象方法,所以可以直接用lamba表达式来写!!!
HashMap实现类及其原理(很重要!!)
1、底层原理和之前讲到的hashset几乎一样,hashset就是基于hashmap实现的。
2、每个Node里包含Entry键值对,hashcode,和链表中后续对象的next
3、具体实现可以找找网上很多博客都有写,因为很重要!!后期可以自己看看源码!!
LinkedHashMap实现类
TreeMap实现类
不可变集合
泛型<>修饰
用泛型or修饰并不是固定某种类型,相反用泛型修饰其实是为了更具通用性!是可以传入任意类型的,在实际用的时候会把泛型变量的地方,全部替换成具体传进来的类型值!
1、泛型类,在定义类的同时,用泛型去修饰,把出现泛型变量的地方全部替换成传输的真实数据类型,比如ArrayList就是一个定义了泛型的实现类,里面对应的方法的参数,变量也都可以用泛型来修饰。
2、泛型方法,在定义方法的同时用泛型去修饰,把方法中出现泛型变量的地方全部替换成传输的真实数据类型。
3、泛型接口,让实现类在定义时就去传入某一具体的类型
4、泛型通配符(?)
在定义类的时候,虽然存在继承关系,但是在用泛型定义的对象上,却是没有关系的!
例如:BMW和BENZ类继承至Car,但是ArrayList和ArrayList和ArrayList一点关系也没有,BMW和BENZ类不能进到Car修饰的参数里。为解决这种问题,用泛型通配符?
一般在定义参数的时候,可以用通配符修饰
可变参数
1、类似于python中的那个kwarg和arg,JAVA中用...来表示,JAVA中可变参数本质上是一个数组