新手小白学java三
- 一、IDEA集成开发工具的安装和使用
- 承接零基础 继续学习面向对象
- 二、final关键字
- 三、抽象类
- 四、接口
- 五、is a(继承关系)、has a(关联关系)、like a(实现关系)
- 总结抽象类与接口的区别(语法层次)
- 六、包机制package与import
- 所谓的包机制(package),其实就是为了方便程序的管理,将不同功能的类分别存放在不同的包下。其使用方法为:package + 包名。
- import:如果两个类不在同一个包下,且A类想要访问B类,则A类可以通过import导入B类所在的包,从而实现直接输入B来调用B,否则需要通过包名.B来调用。
- 注意:如果一个类A在一个包里(代码第一行有package XX),则想要调用此类,需要把A类的全名写上XX.A才可,如果不想这么麻烦,则需要import导入此类:import XX.A就可以通过A调用了。
- 总结import与package
- 访问控制权限(public、protected、默认(非default)、private)
- 范围从大到小排序:public>protected>默认>private
- 七、object类
- 八、匿名内部类
- 九、数组
- 十、排序查找算法
- 十一、String
- 存储原理(String创建的对象存储在方法区中的字符串常量池)(当时创建对象方式不同,存储原理不同)
- String的构造方法
- charAt()方法:返回指定索引处的char值
- compareTo()方法:比较两个字符串的大小
- contains()方法:判断一个字符串中是否包含另一个子字符串
- endswith()方法:判断字符串是否以某个指定的字符串结束
- equals()方法:比较两个字符串是否相同,必须用equals,不能用==,因为不保险,不一定
- getBytes()方法:将字符串对象转换成字节数组(其实就是转换成每个字符的ASCII码)
- indexOf()方法:判断子字符串在字符串中第一次出现处的索引
- isEmpty()方法:判断一个字符串是否为空串""(注意,不是判断是否为null,如果是null,调用此方法会报空指针异常)
- length()方法:返回字符串长度
- lastIndexOf()方法:判断一个子字符串在当前字符串中最后一次出现处的索引
- replace()方法:用一个子字符串代替当前字符串中的另一个子字符串从而得到一个新字符串
- Split()方法:将当前字符串以某个字符为界拆分成若干子字符串,从而得到一个字符串数组
- startsWith()方法:判断某个字符串是否以某个子字符串开始
- subString()方法:截取字符串,其中有参数不同的两种方式
- toCharArray()方法:将一个字符串转换成一个char数组
- toLoewerCase()和toUpCase()方法:转换为小写和大写
- trim()方法:去除字符串前后的空白
- valueOf()方法:注意,此为静态方法,无需new对象,直接通过String.valueOf()调用. :用来将非字符串转换成字符串
- 十二、StringBuffer(初始化容量为16的byte[]数组)
- 对String与Stringbuffer区别的总结
- 十三、包装类型是引用数据类型(分别对应8种基本类型)
- 总结所碰到的经典异常
- 十四、日期类:java.util.Date、java.text.SimpleDateFormat、java.util.Calendar
- 十五、数字类:java.text.DecimalFormat、java.math.BigDecimal
- 十六、随机数类random
- 十七、枚举类(引用数据类型) Enum:可以一个一个列举出来的才建议使用此类型,其中的每一个值可以看做是常量
- 常用类总结(String/StringBuffer/8个保证类/Enum)
- 十八、Exception异常
- 十九、集合collection
- 增强for循环:foreach
- foreach语法格式:缺点是无下标
- Map(集合续)
- hashMap:底层是一维数组,数组中的每个元素存放的是一个单向链表
- hashMap与hashTabe的区别
- java8对hashMap做的改进:当数组中某一条单向链表上的元素个数超过8个,会自动将单向链表转换成红黑树,从而提高查找效率;而当红黑树上的节点数少于6时,会重新将红黑树转换成单向链表。
- treeSet集合:底层实际是treeMap,无序不可重复,但是可以按照元素大小顺序进行排序
- 集合工具类Collections(与Conllection不同),collections是集合工具类,方便集合的操作;collection是集合接口
- 集合的大总结
一、IDEA集成开发工具的安装和使用
自行安装(学生账号可以免费激活)
IDEA的快捷键以及简单设置
快速纠错快捷键:alt+回车
作业题1
承接零基础 继续学习面向对象
二、final关键字
final修饰的方法不能够被覆盖(重写)
final修饰的类不能被继承
final修饰的变量只能赋值一次
final修饰的引用也只能指向一次,但是引用(对象)内部中的属性(变量)可以修改
final修饰的实例变量,系统不会自动赋默认值,必须手动赋值(而正常的实例变量如果不手动复制,系统会自动赋默认值)
final多用来和static一起联合修饰变量——即常量
final总结
三、抽象类
非抽象类继承抽象类时,一定要将抽象类中的抽象方法重写(覆盖)实现
注意:即使是抽象类,也可以使用多态
抽象类总结
面试题:java语言中凡事没有方法体的方法都是抽象方法吗?(错误)——native
四、接口
接口的基础语法
接口的基础语法(续)
注意:接口可以看成是特殊的抽象类,因此接口需要满足抽象类的所有条件,如类实现接口(相当于类继承类),则此类如果是非抽象类,则此类需要将接口中的抽象方法实现(重写)。
类与接口之间的继承关系,叫做实现,用implements表示。如:class A implements B,其效果和类与类之间的继承一样:class C extends class D。但是接口与接口之间仍然是继承:interface E extends interface F。
接口和多态的联合使用
既然接口可以看做是一个特殊的抽象类,那么接口当然也可以像抽象类那样可以多态。
接口的基础语法(续续)
注意:接口与接口之间支持多继承extends,
而类与接口之间也支持多继承(即多实现implements)。
注意:接口与接口之间进行强制类型转换时,即使二者无继承关系,也可以强转。
extends和implements同时出现
interface接口总结
接口在开发中的作用(类似于多态在开发中的作用)
五、is a(继承关系)、has a(关联关系)、like a(实现关系)
总结抽象类与接口的区别(语法层次)
六、包机制package与import
所谓的包机制(package),其实就是为了方便程序的管理,将不同功能的类分别存放在不同的包下。其使用方法为:package + 包名。
import:如果两个类不在同一个包下,且A类想要访问B类,则A类可以通过import导入B类所在的包,从而实现直接输入B来调用B,否则需要通过包名.B来调用。
注意:如果一个类A在一个包里(代码第一行有package XX),则想要调用此类,需要把A类的全名写上XX.A才可,如果不想这么麻烦,则需要import导入此类:import XX.A就可以通过A调用了。
总结import与package
访问控制权限(public、protected、默认(非default)、private)
范围从大到小排序:public>protected>默认>private
七、object类
7.1toString方法:建议所有子类重写此方法
输入引用时,会自动调用该引用的toString()方法
7.2equals方法(所有子类建议重写此方法)
注意 基本数据类型的数据比较可以直接使用==来比较,引用数据类型的数据(如String)需要用equals方法来比较(需要重写equals方法来满足不同类型的需要)
String中重写了toString和equals方法
重写equals方法的模板
toStrings与equals小结
7.3finalize方法(无需手动调用,JVM自动调用来进行垃圾回收,新版本已停用)
因此,有时候可以通过调用system.gc()来建议启动垃圾回收机制(但仅仅是建议,不一定每次都能启动)
7.4 hashcode方法(仅需了解一下)
八、匿名内部类
所谓内部类,就是在类的内部又定义了一个新的类,称为内部类。
匿名内部类:是局部内部类的一种,因没有名字而得名(不建议使用)
九、数组
一维数组的声明/定义
语法格式:
int[ ] array1;
double[ ] array2;
boolean[ ] array3;
String[ ] array4;
注意:
也可以写成int array1[];
double array2[];
String array4[];这种形式。两种形式都可以。
一维数组的初始化
包括:静态初始化和动态初始化两种方式。
静态初始化
int[ ] array = {100,2000,50 };
动态初始化
int[ ] array = new int[5];
这里的5表示数组的元素个数。每个元素默认值是0.
String[ ] array = new String[6];初始化6个长度的String类型数组,每个元素的默认值是null.
何时采用静态初始化?何时采用动态初始化?
一维数组的遍历(用循环)
正序和倒序输出:
如何将一维数组传参
我们一直用的main方法中的String数组是JVM调用main方法时自动传入的默认数组,同时我们用户也可以手动输入参数
引用数据类型的一维数组
此外,虽然数组的数据类型必须一致,但是支持多态。
即:比如一个animal类型的数组,bird和cat是继承animal的两个子类,那么animal类型的数组中可以存储animal类型、bird类型和cat类型的引用,而不单单是只能存储animal类型的引用。
一维数组的扩容
java中:若想对一个数组扩容,则必须创建一个更大的数组,然后将小数组中的元素一一拷贝到大数组中。(这也导致了java中数组扩容效率低)
java已经实现了这种一一拷贝来进行数组扩容的方法
System.arraycopy()方法
源代码:
应用:
基本数据类型和引用数据类型的数组均可以使用此方法
内存图示
二维数组
二维数组的读写
二维数组的遍历
动态初始化 二维数组
注意!!!:不存在一下这种将二维数组传参的方式
数组的小总结
array工具类——java.util.Arrays(java提供了数据工具类,可以调用各种查找和排序算法)工具类中的方法大部分是静态方法
java.util.Arrays工具类
注意:IDEA中可以打开java.util.Arrays类,然后crtl+F12可以查看此类中已经写好的方法
注意:java.util.Arrays中的所有方法都是静态方法,可以通过Arrays.的方式调用方法
十、排序查找算法
排序算法
冒泡排序
缺点:交换次数过多
选择排序:效率高于冒泡排序(因为交换次数少)
解决了冒泡排序交换次数太多的缺点
查找
普通查找
二分法查找(对有序的数组进行查找,因此要先排序,再查找)
十一、String
存储原理(String创建的对象存储在方法区中的字符串常量池)(当时创建对象方式不同,存储原理不同)
如果用以下语法创建字符串,则其内存图如下:
如果是通过new的方法创建字符串对象,则其内存图如下:
注意:因为String是引用数据类型,因此,String s1="abc"中,s1中保存的不是"abc"字符串,而是"abc"字符串的内存地址,即s1是一个引用
字符串的比较(与其他引用的比较相比,有点特殊)
第一种:用String s1 = "hello"的方式创建字符串对象
第二种:用String x = new String(“xyz”)的方式创建字符串对象
因此,使用"“来比较字符串不保险,所以不适用”"来比较,而是使用equals方法比较,sun公司已经在String类中将equals方法重写用来适用于比较字符串
注意:垃圾回收机制不会回收常量,因此垃圾回收机制不会回收字符串。
String的构造方法
String类的toString方法重写了
构造方法1:String(byte[] bytes)(byte数组转成字符串)
构造方法2:String(byte[] bytes, int offset, int length)
构造方法3:String(char[] value, int offset, int count)
String常用构造方法总结
charAt()方法:返回指定索引处的char值
compareTo()方法:比较两个字符串的大小
其实是比较的两个字符串从不相同处的第一个字符的大小(ASCII码的大小)
contains()方法:判断一个字符串中是否包含另一个子字符串
endswith()方法:判断字符串是否以某个指定的字符串结束
equals()方法:比较两个字符串是否相同,必须用equals,不能用==,因为不保险,不一定
##equalsIgnoreCase方法:判断两个字符串是否相等的时候忽略大小写
getBytes()方法:将字符串对象转换成字节数组(其实就是转换成每个字符的ASCII码)
输出结果是:97 98 99 100 101 102
indexOf()方法:判断子字符串在字符串中第一次出现处的索引
isEmpty()方法:判断一个字符串是否为空串""(注意,不是判断是否为null,如果是null,调用此方法会报空指针异常)
length()方法:返回字符串长度
注意判断数组的长度和判断字符串长度是不一样的,判断数组长度是length属性,而判断字符串长度是length()方法。
lastIndexOf()方法:判断一个子字符串在当前字符串中最后一次出现处的索引
replace()方法:用一个子字符串代替当前字符串中的另一个子字符串从而得到一个新字符串
Split()方法:将当前字符串以某个字符为界拆分成若干子字符串,从而得到一个字符串数组
startsWith()方法:判断某个字符串是否以某个子字符串开始
subString()方法:截取字符串,其中有参数不同的两种方式
一、截取从开始下标开始的字符串
二、这里截取的是一个前闭后开区间的字符串
toCharArray()方法:将一个字符串转换成一个char数组
其中返回的char数组chars为{‘我’, ‘是’, ‘中’, ‘国’, ‘人’}
toLoewerCase()和toUpCase()方法:转换为小写和大写
trim()方法:去除字符串前后的空白
valueOf()方法:注意,此为静态方法,无需new对象,直接通过String.valueOf()调用. :用来将非字符串转换成字符串
注意:如果传进来的参数是一个对象,那么此方法会调用该对象的toString()方法。
十二、StringBuffer(初始化容量为16的byte[]数组)
思考:在正常开发过程中,频繁的字符串拼接会导致?内存空间的浪费,给方法区中的字符串常量池带来很大的压力
因此如果以后需要进行大量的字符串拼接,建议使用JDK自带的StringBuffer或者StringBuilder类
StringBuffer()的构造方法(有参/无参)
无参构造:
有参构造:
append()方法:字符串的拼接
StringBuffer如何优化?
StringBuffer与StringBuilder的区别
对String与Stringbuffer区别的总结
十三、包装类型是引用数据类型(分别对应8种基本类型)
为什么要提供8种包装类?
因为8种基本数据类型不够用,在许多情况下需要使用对应的包装类型。
8种包装类型
前6个的父类Number是抽象类,无法实例化对象。
Integer
Integer的装箱拆箱方法
Integer的构造方法
通过Integer中的常量来获得int类型的最大值和最小值
在JDK1.5之后,支持自动装箱和自动拆箱
注意:有特殊情况!!!:java将-128到127的包装类Integer对象已经提前创建好,存放在方法区的整数型常量池中,因此,当有通过Integer创建在此范围内的对象时,在Integer类加载时将256个对象加载到整数型常量池中,无需new创建,而是直接去常量池中获取,因此,会有以下特殊情况发生
对于此时的内存图:
Integer的常用方法
parseInt()静态方法:将字符串类型String转换成int类型
toBinaryString()静态方法:将整数转换成二进制字符串
3个valueOf()静态方法:String、Integer、int类型之间的转换
String、int、Integer三种数据类型的转换总结!!!!!!
总结所碰到的经典异常
十四、日期类:java.util.Date、java.text.SimpleDateFormat、java.util.Calendar
Date的构造方法(用来获取当前系统时间)(有参/无参)
无参构造方法:
有参构造方法:
SimpleDateFormat类:使用java.text包下的SimpleDateFormat类来将Date类对象转换成一个日期字符串,即日期转成字符串
parse()方法:将内容是日期的字符串String转换成Date类型
currentTimeMillis()方法:获取从系统时间1970.1.1 00:00:00距今的毫秒数——可以用来统计方法运行的耗时
System类下的方法总结
十五、数字类:java.text.DecimalFormat、java.math.BigDecimal
DecimalFormat:数字格式化
BigDecimal:属于大数据,精度极高;不属于基本数据类型,属于java对象(引用数据类型),这是SUN公司提供专门用于财务软件中的类
十六、随机数类random
nextInt()方法:产生随机数(分为有参/无参)
无参:
有参:
十七、枚举类(引用数据类型) Enum:可以一个一个列举出来的才建议使用此类型,其中的每一个值可以看做是常量
枚举类型总结
常用类总结(String/StringBuffer/8个保证类/Enum)
十八、Exception异常
异常提醒机制的作用
异常的存在形式——(类/对象)
java异常处理机制
Exception类继承Throwable父类,而Exception其下又可以分类两大类子类:异常直接子类和运行时异常子类(RunTimeException)。
所有的异常都需要new对象,因此所有的异常都发生在运行阶段。
其中,所有的异常的直接子类又叫做编译时异常:并不是指这些异常是在编译阶段发生的异常,而是指必须在编写程序时预先对这些异常进行处理,否则编译器会报错。
而RunTimeException是在运行时抛出的异常:在编写程序时可以处理,也可以不处理。
编译时异常(又称受检异常/受控异常)与运行时异常(又称未受检异常/非受控异常),但是他们均发生在运行阶段。
编译时异常发生概率较高,运行时异常发生概率较低。
两种异常的处理方式
第一种:在方法声明位置,使用throws关键字,throws后面可以跟多个异常(用逗号隔开)
例子:
上述问题处理方式:
注意:倘若某个方法出了异常,且采用throws上报的方式处理异常,则此方法的后续代码不会执行。
第二种:使用try…catch语句进行异常的捕捉
两种异常处理方式的选择
异常i对象的常用方法
1.exception.getMessage()方法:获取异常的简单描述信息
2.exception.printStackTrace()方法:打印异常追踪的堆栈信息
如何查看异常信息从而快速调试程序
try…catch中的finally子句:finally中的子句最后执行且一定执行
下述例子,存在bug:
为了改进,解决fis关闭的问题,使用finally子句,可以保证fis最终一定会关闭:
注意:try…finally,没有catch也可以执行。
即使try中的代码包含return,finally语句仍会执行!!!!多么强大
注意,如果try中代码有执行system.exit(0),即退出JVM,那么finally子句不会执行
Finally面试题:非常诡异的结果与执行过程
其内部执行的过程如下:
final、finally、finalize的区别
自定义异常
异常在实际开发中的应用
异常与方法覆盖:重写之后的方法不能比重写之前的方法抛出更多(宽泛)的异常,但是可以更少(范围更小)
十九、集合collection
在java中,集合分为两类:1.单个方式存储元素;2.键值对存储元素(key:value)
集合中存储的是对象/引用的内存地址
不同集合可能对应不同的数据结构
集合的继承结构图
collection中的List和Set两种类型的集合
List集合的存储特点:有序可重复,存储元素有下标
List接口下有常用的三个类:ArrayList(数组,非线程安全)、LinkedList(双向链表)、Vector(数组,线程安全)
Set集合的存储特点:无序不可重复,元素没有下标
Set接口下有常用的类:hashSet(底层实际上是哈希表hashMap)。
同时,Set下的有一个子类接口sortedSet,而其下有TreeSet类(底层实际是TreeMap——采用二叉树)实现了sortedSet。
Map集合继承结构图
总结
Collection接口中的常用方法
add()方法:往集合添加元素
remove()方法:删除集合中的某一个元素
底层调用了equals方法判断。详情见下面的contains方法。
size()方法:获取集合中元素个数
clear()方法:清空集合
contains()方法:判断当前集合中是否包含某一元素
注意:contains方法地层调用了equals方法,因此以下例子要注意!!!
isEmpty()方法:判断集合中元素个数是否为0
toArray()方法:将集合转换成数组
重点方法***:iterator集合迭代!!!:注意:集合结构发生改变,Iterator必须要重新获取。
而返回的迭代器Iterator中有3个方法:
迭代器Iterator的3个方法:hasNext()、next()、remove()
List中的特有的常用方法
add(int index, E element):在指定位置上插入元素
get():根据下标获取下标对应位置的元素
indexOf():获取指定元素在集合中出现第一次的索引下标
lastIndexOf():获取指定元素在集合中出现最后一次的索引下标
remove(int index):删除指定下标位置的元素
set():用指定元素替换指定下标位置的元素
ArrayList:非线程安全
ArrayList的初始化容量10,
ArrayList的底层是Object类型的数组
ArrayList自动扩容,每次扩容至原来数组的1.5倍,建议给定一个预估计的初始化容量,从而减少扩容次数,这是ArrayList重要的优化
linkedList:底层是双向链表结构
vector:底层是数组,默认容量10,每次扩容为原来2倍的容量
泛型:用来指定集合中存储的数据类型
什么是泛型:如:List = new ArrayList(),表示List集合中只能存储animal类型的对象引用。
如果对应集合使用泛型,则相应的迭代器Iterator也必须用泛型。那么该迭代器的犯法Next()返回的对象类型也是相应的数据类型。
自动类型推断机制(钻石表达式)JDK8之后新引入的特性
其实就是如下图所示:new ArrayList<>中的<>不需要写类型animal,会自动判断。
自定义泛型
增强for循环:foreach
foreach语法格式:缺点是无下标
for(元素类型 变量名 : 数据或者集合){
}
如:
Map(集合续)
Map中的常用方法
clear():清空map集合
containsKey()和containsValue():判断Map集合中是否包含某个key/value,底层通过调用equals()方法来比较
get():通过key获取对应value
isEmpty():判断map是否为空(元素个数是否为零)
keySet():获取map集合中的所有key
put():向MAP集合中添加键值对
remove():通过key删除键值对
size():获取map集合中键值对的个数
values():获取map集合中的所有value,返回一个collection
entrySet():将map集合转换成set集合
使用Map集合中的常用方法的组合实现遍历
第一种方式:获取所有的key(用keySet()方法),通过遍历key来遍历value(用get()方法)
同样用keySet()方法获取key,然后用foreach遍历
第二种方式:使用entrySet()方法将map集合转换成set集合
也可以使用foreach来遍历(效率高):
hashMap:底层是一维数组,数组中的每个元素存放的是一个单向链表
默认初始化容量16,加载因子是0.75
手动设置初始化容量的话,hashMap集合的初始化容量必须是2的倍数。
哈希表数据结构:数组与单向链表的结合
map.put(k,v)方法原理
map.get(k)方法原理
重写hashCode()与equals()方法:使用IDEA一键生成,注意,这两个办法必须同时重写
终极结论
hashMap与hashTabe的区别
java8对hashMap做的改进:当数组中某一条单向链表上的元素个数超过8个,会自动将单向链表转换成红黑树,从而提高查找效率;而当红黑树上的节点数少于6时,会重新将红黑树转换成单向链表。
properties(又称为属性类对象)是一个map集合,继承hashTable,其key与value均为String数据类型,是线程安全的
properties的存取数据的方法:setProperty(k,v)和getProperty(k)
treeSet集合:底层实际是treeMap,无序不可重复,但是可以按照元素大小顺序进行排序
自定义的类型的对象想要存放到treeSet中,需要实现comparable接口才行(需要根据业务逻辑需求实现comparable接口中的compareTo()方法)
treeSet/treeMap集合采用的是二叉树的中序遍历方式,Iterator也是采用的中序遍历。
treeSet集合中元素可排序的第二种方式:使用比较器:comparator(第一种方式是前面说的实现comparable接口的方式)
排序方法总结
集合工具类Collections(与Conllection不同),collections是集合工具类,方便集合的操作;collection是集合接口
synchronized()方法:将非线程安全的arrayList变成线程安全的
sort(list)方法:将list中的元素排序(注意:如果元素是自定义的类,记得实现comparable就扣,按照业务逻辑实现compareTo()方法)
集合的大总结
ArrayList
创建:ArrayList arr = new ArrayList<>();
添加:arr.add("zhangsna ");
取出:arr.get(1);通过下标去元素
遍历:两种:一、for(i = 0 ;i < arr.size();i++){
system.out.println(arr.get(i));
}
二、Iterator it = arr.iterator();
while(it.hasNext()){
system.out.println(it.next());
}
或者:for(String s : arr ){
system.out.println(s);
}
HashSet
创建:HashSet arr = new HashSet<>();
添加:arr.add("zhangsna ");
取出:无
遍历:两种:一、for(String s : arr ){
system.out.println(s);
}
二、Iterator it = arr.iterator();
while(it.hasNext()){
system.out.println(it.next());
}
TreeSet(属于sortedSet,自动排序)
HashMap
properties
未完待续