Java基础
第一阶段Java基础
windows快捷键
- win+r:cmd
- win+e:我的电脑
- 下方任务栏右键/ctrl shift esc:任务管理器
- shift+delete:永久删除
- ctrl+d:复制当前行到下一行(idea)
Dos命令
打开cmd
- win+r
- 文件夹按住shift+鼠标右键 powershell
常用DOS(英文模式)
- 切盘 D:
- 查看当前目录下文件 dir
- 切换目录
- cd 进入
- cd… 上一级
- cd /d E:\IDE 从当前盘切到E盘的IDE目录(cd \d 路径)
- 清屏 cls
- 退出终端 exit
- 查看电脑ip ipconfig
- ping命令:ping 网址 (得到该网址信息,一般用于测试网络是否正常)
- md test:创建文件夹
- rd test:删除文件夹
- cd >a.txt:创建文件
- del a.txt:删除文件
java基础语法
运行机制
- 工具jdk
- java跨平台的实现:jvm
- 编译:javac 文件名.java 会生成一个class文件
- 运行:Java 文件名
编译型、解释型
安装idea
创建项目
为方便结构管理,一般创建方式:
- creat new project->创建空项目->file-new-Module->选中java(SDK为jdk1.8)一路next创建项目
- 打开project structure->SDK(jdk1.8),language(8)->apply
- src中创建class写代码
标识符
- 首字符a-z、A-Z、$、下划线
- 首字符后可以是a-z、A-Z、$、下划线、数字 的任何字符组合
- 标识符大小写敏感
数据类型
- java是强类型语言 所有变量必须先定义后才能使用
- 分两类
- 基本类型:数值类型(int float char)boolean类型(true false)
- 引用类型:类、接口、数组
//整数
int num1 = 10; //最常用4字节
byte num2 = 20; //1字节-128-127
short num3 = 30; //2字节-32768-32767
long num4 = 30L; //long类型要在数字后面加个L 8字节
//小数:浮点数
float num5 = 50.1F; //float类型要在数字后面加个F 4字节
double num6 = 3.1415926; //8字节
//字符
char name = 'A'; //2字节
String name = "王博";
//布尔值:占1位 值只有true false
boolean flag = true;
字节
- 位:bit 计算机 内部数据 存储的最小存储单元 11001110是一个八位二进制数
- 字节:byte 计算机中 数据处理 的基本单位,习惯上用B表示
- 1B=8bit
- 字符:计算机中使用的字母、数字、字、符号
进制、转义字符
- 整数拓展:二进制0b 八进制0 十六进制0x
int i = 010; //八进制 8
int i1 = 0x11; //十六进制 17
- 浮点数拓展:最好完全避免浮点数进行比较
float 有限 离散 舍入误差 大约数 接近但不等于
但是 类似银行业务如何表示?-> BigDecimal 数学工具类(先有个了解)
- 字符拓展:
所有的字符本质还是数字
a - 97 A - 65 (Unicode表: 2字节 编码 0-65536 数字与字符对应)
- 转义字符:
//转义字符
// \t 制表符相当于一个Tab
// \n 换行
//...
类型转换
- 低到高:byte,short,char -> int -> long -> float -> double; java是强类型语言 所以进行有些运算时要用到类型转换
- 运算中,不同类型的数据先转化位同一类型,然后运算
- 强制转换 低 = (类型)高
- 自动转换 高 = 低
- 注意点
- 不能对bool值进行转换
- 不能把对象类型转换为不相干的类型
- 高容量到低容量要强转 int a = 128; byte b = (byte) a; sout(b) //-128溢出
- 转换的时候可能存在内存溢出,或者精度问题(float转int精度流失 (int)0.5=0)
变量
- 局部变量:必须申明和初始化
- 实例变量:方法外面 类里面 从属于对象(类) ,如果不初始化 默认值为0、0.0、false、null
- 类变量:static修饰
常量
- 常量是初始化之后就不可以改变的值,可以理解为特殊变量,其值被设定后不允许被改变
- final 常量名 = 值; final double PI = 3.14;
- 常量名一般用大写
运算符
算术、关系、赋值、逻辑(&&,||,!)、条件(? :)、扩展赋值(+=、/=)、位运算符(了解)
- 几个注意
- ++ – 自增 自减 一元运算符 int b = a++,先赋值 再自增;int b = ++a,自增后赋值
- 常用Math类
double a =Math.pow(3,2); //3的2次方
- 逻辑运算符的短路:a && b a假结果直接假,b不执行;a || b a真结果真,b不执行
- 位运算(& | ^ ~ >> << >>>)无短路 二进制相关
A = 0011 1100;
B = 0000 1101;
A&B = 0000 1100; /
A|B = 0011 1101; //并
A^B = 0011 0001; //亦或 同0异1
~B = 1111 0010; //取反
//<< *2 >> /2 左移乘二 右移除二
2<<3; //2 *2*2*2=16
- 字符串连接 + 有先后
int a = 10;
int b = 20;
System.out.println(""+a+b); //1020 String
System.out.println(a+b+""); //30 String
- 注意优先级
包机制
- 包的本质是文件夹
- 一般将公司域名倒置作为包名:com.mihayoo.www
- 导包import,且必须在package下面
- 尽量不要让包里面的名字重复
- import com.mihayoo.base.*;导入base包下全部类
JavaDos
JAVADOC命令是用来生成自己的API文档的 idea中/**回车如下
- @author
- @version
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
命令行中 javadoc -encoding UTF-8 -charset UTF-8 Hello.java //把该java文件编译成一则文档可阅读
java流程控制
用户交互Scanner
java提供的工具类java.util.Scanner 来获取用户的输入
-
Scanner s = new Scanner(System.in);
-
Scanner类的next()与nextLine()方法获取输入的字符串,读取之前用hasNext()与hasNextLine()判断是否还有输入的数据
-
next():不能得到带有 空格 的字符串
-
nextLine():可以获得空白 返回输入回车之前的所有字符
public class Demo1 { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("next方式接收"); //判断用户是否输入字符串 if(scanner.hasNext()){ //使用nextLine方式接收 String str = scanner.nextLine(); System.out.println("输出"+str); } //io流类不关闭会一直占用资源 scanner.close(); } }
顺序、选择、循环结构
-
顺序:从上到下
-
选择:
- if() 单选
- if() else 双选
- if() else if() else 多选
- switch case… default多选
- switch语句中变量类型可以是byte\short\int\char
- java se 7开始switch语句支持字符串String类型
- case 标签必须为字符串常量或字面量(数字1 2 3…/字符a b c A B C…)
- case穿透 无break会继续向下执行
-
循环:
-
while(boolean){循环内容}:
-
先判断后执行
-
只要boolean为true就一直循环,通常需要一个让boolean表达式失效的方式来结束循环,小部分情况下一直循环,如服务器的请求响应监听等
-
-
do{循环内容} while(条件):
- 先执行后判断
- 保证至少执行一次
-
上面已经万能了,for更简单
-
支持迭代,有效、通用、灵活
-
执行次数在执行前就已经确定
-
for(初始化;条件判断;迭代){循环体}
-
快捷 100.for回车
-
for( , , ){} 死循环
-
增强for循环(简化写法)(用于循环数组、集合)
int[] numbers = {1,2,3,4,5,6}; for(int i = 0;i<6;i++){ System.out.println(numbers[i]); } //========================================================= for(int x:numbers){ System.out.println(x); }
-
-
break & continue & goto
- break在任何循环语句的主体部分,都可以break空指循环流程,break用于强行退出循环,不执行循环中剩余的语句
- continue语句用在循环语句体中,用于终止某次循环过程,即跳过本次循环体中尚未执行的语句,接着进行下一次循环是否执行的判定
- goto很早就有,但是java用的不多,目前仍然是一个保留字 (不掌握)
Debug
IDEA运行键右边的 七星瓢虫
- 先打断点 然后虫debug 一步步查看
java方法
方法
-
方法命名:首字母小写的驼峰
-
方法包含于类或对象中 是一类问题的步骤的有序组合 在程序中被创建在其他地方被引用
-
设计原则:一个方法只完成一个功能,利于后期的扩展
-
修饰符 返回值类型 方法名(参数类型 参数名){方法体…return 返回值;}
-
main()方法尽量 简介、干净
-
形参:用来定义作用 只是个名字 随意
-
实参:实际调用传递的参数
-
return 0;相当于终止方法,return 代表方法的结束
-
方法调用
-
当方法返回一个值的时候,方法调用通常被当做一个值
-
int larger = max(30,40);
-
如果方法返回值void,方法调用一定是一条语句
-
System.out.println(); //alt按住点 看源码
-
方法重载
- 重载:一个类中,有相同的函数名称,但形参不同的函数
- 方法重载的规则
- 方法名称必须相同
- 参数列表必须不同(个数、类型、排列顺序)
- 方法的返回类型可以同 也可以不同
- 仅仅返回类型不同 不足以成为方法的重载
可变参数
相当于数组,并不知道具体要传递多少参数
- 方法声明中,在指定参数类型后+省略号(…)
- 一个方法中只能有一个可变参数,且必须是最后一个参数,其他普通参数都要在它前面声明
public static void printMax(double... numbers){
if(numbers.length == 0){
System.out.println("wrong");
return;
}
double result = numbers[0];
//排序
for(int i =1;i< numbers.length;i++){
if(numbers[i] > result){
result = numbers[i];
}
}
System.out.println("max value is" + result);
}
递归
-
很容易理解A方法调用B方法,递归就是A方法调用A方法,自己调用自己
-
利用递归可以用简单的程序解决复杂问题,复杂问题 层层转化为 一个与原问题相似的规模较小的问题来解决,递归只需要少了的程序就可以描述出解题过程需要的多次重复的计算,代码量减少,递归的能力在于用有限的语句来定义对象的无限集合
-
递归包含2部分
- 递归出口:什么时候不调用自身方法(必须有 否则死循环)
- 递归体:什么时候需要调用自身方法
-
相当于栈 (主要了解递归思想 调用深度太高性能损失大 不推荐常用)
数组
数组定义
- 相同数据类型
- 有序
- 数组元素用下标访问
数组声明创建
- 声明推荐:dataType[] arrayName;
- java用new操作符创建数组:dataType[] arrayName = new dataType[arraySize];
int[] nums;
nums = new int[10];
//int[] nums = new int[10]
nums.length; //获取数组长度
内存分析
java内存
- 堆:存放new的对象和数组 可以被所有的线程共享,不会存放别的对象引用
- 栈:存放基本变量类型(会包含这个基本类型的具体数值)引用对象的变量(会存放这个引用在堆里面的具体地址)
- 方法区:可以被所有线程共享 包含了所有class和static变量
三种初始化
-
静态初始化
int [] array = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)};
-
动态初始化
int[] array = new int[6];
-
默认初始化:数组是引用类型,元素相当于类的实列变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化 默认0
数组特点
- 长度确定,一旦创建,大小不可变
- 元素同类型
- 元素可以是任何数据类型,包括基本类型和引用类型
- 数组变量属于引用类型,数组可以看成是对象,数组中每个元素相当于该对象的成员变量
- 数组本身就是对象,java中对象在堆中,所以数组无论保持原始类型还是其他对象类型,数组对象本身是在堆中
- 下标合法区间是0到length-1,防止越界,越界报错:ArrayIndexOutofBounds
数组使用
- 增强for循环 for-each:for(int array : arrays){ System.out.println(array) } 快捷arrays.for回车 没有下标
- 当方法参数
- 当方法返回值
public class Reverse {
public static void main(String[] args) {
int[] array = {1,2,3,4};
int[] reverse = reverse(array);
for (int i : reverse) { //reverse.for回车 增强for循环 一般用于打印
System.out.println(i);
}
}
//反转数组
public static int[] reverse(int[] array){
int[] result = new int[array.length];
for (int i = 0,j = result.length-1;i<array.length;i++,j--){
result[j] = array[i];
}
return result;
}
}
多维数组
-
多维数组可以看成是 数组的数组 比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
-
二维数组:
int[][] array = new int[2][5]; //可以看成一个两行五列的数组
Arrays类
-
数组的工具类 java.util.Arrays
-
包含操作数组的方法
-
[jdk帮助文档]( jdk11在线API,jdk11在线参考手册,jdk11中文在线API,jdk11中文在线参考手册,jdk11在线中文chm文档,jdk11在线中文chm文档 - (mklab.cn) )
-
常用
//打印数组元素 int[] a = {1,2,3,4}; System.out.println(Arrays.toString(a)); //数组元素排序 升序 Arrays.sort(a); //数组赋值:fill方法 Arrays.fill(a,0) //全填充0 //比较数组:equals方法;二分查找数组元素:binarySearch方法
-
Arrays类中等方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用
冒泡排序
public class Maopao {
public static void main(String[] args) {
//外层循环,判断我们这个要走多少次;
//内层循环,比价判断两个数,如果第-一个数,比第二个数大,则交换位置
//每一次比较次数会减少 直至结束
//直接记下 闭眼写
int[] array = {5,6,2,3,7,0,1,4};
int[] result = bubbleSort(array);
System.out.println(Arrays.toString(result)); //[0, 1, 2, 3, 4, 5, 6, 7]
}
//升序 记i=0~length-1;j=0~length-1-i;if(array[j]>array[j+1])
public static int[] bubbleSort(int[] array){
int temp = 0;
for (int i = 0; i< array.length-1; i++){
for (int j = 0; j< array.length-1-i; j++){
if(array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}
}
稀疏数组
右边的稀疏数组也相当于一个9行3列的二维数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cPRYcahv-1655426416620)(https://cdn.jsdelivr.net/gh/wangbo-ship/images/xishusz.png)]
面向对象
面向过程 & 面向对象
- 面向过程思想:线性思维,第一步、第二步、。。。处理较为简单问题
- 面向对象思想:物以类聚、分类思维,思考问题先对问题分类,然后对分类但素思考,最后对某个分类下的戏界金熊面向过程的思考,处理复杂、多人协作问题
- 面向对象本质:以类的方式组织代码,以对象党组织(封装)数据
- 类、是抽象的,是对对象的抽象
- 三大特性:封装、继承、多态
@类种方法调用
方法种类:
-
静态方法:带static关键字,其他类中 调用该方法 直接调用
-
非静态方法:不带static关键字,其他类中调用该方法 需要先实例化该方法所在的类
public class Demo02{ public static void main(String[] args) { Demo01 demo01 = new Demo01(); demo01.nonStaticFun(); } }
-
同一个类中静态方法不能调用非静态方法
- 理解:static静态方法 是和类一起加载的,无static的非静态方法只有在类实例化后才存在,所以相当于一个存在的不能调用不存在的
-
实际参数 和 形式参数 类型要对应相同
-
@值传递和引用传递
类与对象的关系
类是一种抽象数据类型,是对某一类事物的整体描述,不代表某一个具体事物,用来定义某一类具体事物的特点和行为
对象是抽象概念的具体实例:王博是人的一个具体实例,旺仔是狗的一个具体实例,能体现出特点功能的具体实例而不是一个抽象的概念
创建 初始化 对象
-
new关键字创建对象
-
new创建,除了分配内存空间之外,还会给创建好的对象 进行默认的初始化 以及 对类中构造器的调用
public class Application { //一个项目只应该存在一个main方法 public static void main(String[] args) { //类:抽象的 需要实例化 //类实例化后返回一个自己的对象 //xiaoming对象就是一个Student类的具体实例 Student xiaoming = new Student(); Student xiaohong = new Student(); xiaoming.name = "小明"; xiaoming.age = 2; System.out.println(xiaoming.name); System.out.println(xiaoming.age); xiaohong.name = "小红"; xiaohong.age = 1; System.out.println(xiaohong.name); System.out.println(xiaohong.age); } }
//学生类 public class Student { //属性 String name; //默认初始化 null int age; //默认 0 //方法 public void study(){ System.out.println(this.name+"在学习"); } }
-
类中的构造器也成为构造方法,是在进行创建对象时候必须要调用的,而且构造器有两个特点
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
-
构造器必须要掌握
Alt + insert
构造器:
- 和类名相同
- 没有返回值
作用:
- new 本质在调用构造方法
- 初始化对象的值
注意:
- 定义有参构造后,如果想使用无参构造,显示定义一个无参构造
创建对象内存分析
方法区是属于堆的特殊的一部分
类、对象小结
-
类与对象:类是一个模板,抽象;对象是一个具体的实例
-
方法:定义、调用
-
对象的引用
- 引用类型:除了8大基本类型外的类型,对象是通过引用来操作的:栈—>堆(地址)真是是操作堆,只是用的是栈里面简单的引用
-
属性:成员变量
- 初始化:数字 0、0.0;char u0000;boolean false;引用 null;
- 修饰符 属性类型 属性名 = 属性值
-
对象的创建和使用
- 必须使用new关键字创造对象(类的一个实例),构造器
- 对象的属性:wangbo.name
- 对象的方法:wangbo.study()
-
类
- 静态属性 属性
- 动态行为 方法
封装
核心:属性私有、get/set方法 用get、set方法对属性操作
快捷键:先定义私有属性 然后 alt + insert 自动生成get/set方法
意义:提高安全性保护数据、隐藏代码实现细节、统一接口、提高系统可维护性
继承
-
继承的本质是对某一批类的抽象
-
extends 扩展,子类是父类的扩展,子类可以继承父类的全部方法,但私有的东西无法继承
-
JAVA中只有单继承没有多继承(直接继承只能一个,间接继承可以多个)
-
继承是类和类之间的一种关系,除此之外类和类之间的关系还有依赖、组合、聚合
-
继承关系的两个类,一个是子类(派生类),一个是父类(基类),子类继承父类,使用关键字extends来表示。
-
子类和父类之间,从意义上讲应该是 子类 is a 父类(如 Teacher is a Person、Student is a Person)
-
public > protected > default(默认)> private
-
java中 所有类 都默认直接或者间接继承Object类
-
super 调用父类的方法和属性
//父类 public class Person { //若为私有则无法继承 protected String name = "王博"; } //学生类 public class Student extends Person{ private String name = "wangbo"; public void test(String name){ System.out.println(name); System.out.println(this.name); //调用该类的 System.out.println(super.name); //调用父类的 } } public class Application { //一个项目只应该存在一个main方法 public static void main(String[] args) { Student student = new Student(); student.test("wb"); } }
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
this:
-
代表的对象不同:
this:本身调用这个对象
super:代表父类对象的引用 -
前提
this:没有继承也可以使用
super:只能在继承条件才可以使用 -
构造方法
this() ;本类的构造
super():父类的构造!
方法的重写
-
重写要有继承关系,子类重写父类的方法 与属性无关
- 方法名称必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大,但不能缩小
- 抛出异常:范围可以被缩小,但不能扩大
-
重写 子类的方法名称和父类必须要一致,方法体(内容)不同
-
为什么要重写
- 父类的功能,子类不一定需要或者不一定满足
- 重写快捷键 Alt + Insert ;override;
static修饰的方法归类所有,叫类的成员变量,不是对象成员
多态
//工具类
public class Application {
//一个项目只应该存在一个main方法
public static void main(String[] args) {
//一个类的对象的实际类型是确定的
//new Student();
//new Person();
//但是可以指向这个对象的引用类型是不确定的(可以是父类型)
Student s1 = new Student(); //正常理解 Student能调用自己的或者继承父类的方法
Person s2 = new Student(); //父类的引用指向子类 但是不能调用子类独有的方法
Object s3 = new Student(); //Object类是所有类的祖宗类
//s2是父类的引用指向子类 如果子类重写了父类方法优先执行子类方法 如果子类没有重写则执行父类方法
//如果父类没有方法则子类不存在重写 无法调用任何方法
s1.run(); //son跑
s2.run(); //son跑 子类重写了父类的方法,执行子类的方法
s1.eat(); //son吃
s2.eat(); //error 父类没有eat方法无法执行 IDE会强制转化((Student)s2).eat();高转低要强制转换
}
}
//父类
public class Person {
public void run(){
System.out.println("father跑");
}
}
//子类
public class Student extends Person {
@Override
public void run(){
System.out.println("son跑");
}
public void eat(){
System.out.println("son吃");
}
}
下面这个链接讲点很清楚:多态中调用成员方法是 编译看左(左边的类中有没有这个成员) 运行看右(运行的是右边具体类中的该成员)
[父类引用指向子类]
多态注意
-
多态是方法的多态,属性没有多态
-
父类和子类 否指报错类型转换异常ClassCastException
-
存在条件:继承关系,方法要重写,父类引用指向子类对象:Father f1 = new Son()
-
下面除外
- static 方法,属于类,不属于实例
- final 修饰属于常量 无法改变
- private方法
-
Person obj = new Student(); //低转高 自动 但是可能会丢失一些方法
-
父类转换为子类 高转低 需要强制转换
instanceof
-
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
-
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
-
instanceof是用于检查对象是否为指定的类型,通常在把父类引用强制转换为子类引用时要使用,以避免发生类型
转换异常(ClassCastException) 。 -
多态里的那个instanceof不是很明白报错和false的区别,查了资料后大概懂了
A(对象) instcnaceof B(类)结果为boolean型
A和B比较之前会先判断A能不能转换成B类型,能则通过,不能则编译报错
例如
Person person = new Student();
Object object = new Student();
person instanceof String之所以编译会报错是因为person是Person类型,而String是final类型,两者不能转换
而object instanceof String中object是Object类型,String是Object的子类也继承了Object类型,所有能类型转换,编译通过
编译通过后会把A和B比较,如果A是B本类或者子类的对象,结果就是true,反之就是flase
因此object instanceof String,object这个对象不是String的本类或子类,所以出false
static
1)static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
2)static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
3)static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
抽象类
- abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
- 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
接口
//interface定义的关键字 接口都需要有实现类
public interface UserService {
//接口中的所有定义其实都是抽象的 默认省略public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
// 类 可以实现接口:类 implements 接口
// 实现了接口的类需要重写接口中的方法
// 接口可以多继承 与抽象类不同 抽象类只能extends单继承
public class UserServiceImpl implements UserService,TimerService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
接口作用
- 约束
- 定义一些方法,让不同的人实现
- 接口中的方法都是public abstract
- public stratic final
- 接口不能被实例化,接口中没有构造方法
- 可以实现多个接口
- 实现接口必须重写所有的方法
内部类
内部类就是在一个类的内部再定义一个类:A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
异常
异常处理机制
- 抛出异常
- 捕获异常
- 异常处理五个关键字
- try、catch、finally、throw、throws
- 快捷键:Ctrl + Alt + T
//需要捕获多个异常:范围从小到大
try{ //try监控区域
new Test().test(1/0);
} catch (Error e){ //catch(想要捕获的异常类型)捕获异常
System.out.println("Error");
} catch (Exception e){
System.out.println("Exception");
} catch (Throwable t){
System.out.println("Throwable");
} finally { //处理善后工作 可以省略
System.out.println("finally");
}
JAVA常用类、集合、IO流
-
文档:
API
- Object类
- hashcode()
- toString()
- clon()
- getClass()
- notify()
- wait()
- equals()
- Math类
- 常见数学运算
- Random类
- 生成随机树 UUID
- File类
- 创建文件
- 查看文件
- 修改文件
- 删除文件
- 包装类
- 自动装箱、拆箱
- Date类
- Date
- SimpleDateFormat yyyy-MM-dd HH:mm:ss
- Calender(建议使用)
- String类
- 不可变性 final 操作量较少
- StringBuffer类
- 可变长 append() 多线程数据量较大 效率低 安全
- StringBuilder类
- 可变长 单线程数据量较大 效率高 不安全
集合
-
Colelction
- List(有序可重复)
- ArrayList:add remove contains size
- LinkedList:getFirst() getLast() removeFirst() addFirst()
- Vector
- Stack
- Set(无序不可重复)
- HashSet(常用)
- TreeSet
- Iterator
- List(有序可重复)
-
Map
- HashMap(重点、高频)
- jdk1.7:数组+链表
- jdk1.8:hash表=数组+链表+红黑树
- TreeMap
- HashMap(重点、高频)
-
Collections 工具类
-
泛型 <> 约束,避免类型转换之间的问题
1 Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。 2 List 接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。 3 Set Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。 4 SortedSet 继承于Set保存有序的集合。 5 Map Map 接口存储一组键值对象,提供key(键)到value(值)的映射。 6 Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。 7 SortedMap 继承于 Map,使 Key 保持在升序排列。
Set和List的区别
- \1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
- \2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
- \3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>
集合实现类(集合类)
Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现。
标准集合类汇总于下表:
序号 | 类描述 |
---|---|
1 | AbstractCollection 实现了大部分的集合接口。 |
2 | AbstractList 继承于AbstractCollection 并且实现了大部分List接口。 |
3 | AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问。 |
4 | LinkedList 该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:List list=Collections.synchronizedList(newLinkedList(...)); LinkedList 查找效率低。 |
5 | ArrayList 该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。 |
6 | AbstractSet 继承于AbstractCollection 并且实现了大部分Set接口。 |
7 | HashSet 该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。 |
8 | LinkedHashSet 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。 |
9 | TreeSet 该类实现了Set接口,可以实现排序等功能。 |
10 | AbstractMap 实现了大部分的Map接口。 |
11 | HashMap HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。 |
12 | TreeMap 继承了AbstractMap,并且使用一颗树。 |
序号 | 类描述 |
---|---|
1 | Vector 该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。 |
2 | Stack 栈是Vector的一个子类,它实现了一个标准的后进先出的栈。 |
如何使用迭代器
通常情况下,你会希望遍历一个集合中的元素。例如,显示集合中的每个元素。
一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或 ListIterator接口。
迭代器,使你能够通过循环来得到或删除集合的元素。ListIterator 继承了 Iterator,以允许双向遍历列表和修改元素。
遍历Arraylist
public class Test{
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用 For-Each 遍历 List
for (String str : list) { //也可以改写 for(int i=0;i<list.size();i++) 这种形式
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i<strArray.length;i++) //这里也可以改写为 for(String str:strArray) 这种形式
{
System.out.println(strArray[i]);
}
//第三种遍历 使用迭代器进行相关遍历
Iterator<String> ite=list.iterator();
while(ite.hasNext())//判断下一个元素之后有值
{
System.out.println(ite.next());
}
}
}
三种方法都是用来遍历ArrayList集合,第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度。
遍历Map
public class Test{
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
//第一种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
}
//第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第三种:推荐,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第四种
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {
System.out.println("value= " + v);
}
}
}
IO流
I0流简介:
概述:
I(Input,输入)/0(Output, 输出)流,是Java中 用来传输数据的方式.
划分:
-
按照流向分:
输入流:读数据. 输出流:写数据. -
按照操作分:(字节010011 字符abcde)
-
字节流:以字 节为单位来操作数据.
InputStream:字节输入流的项层抽象类.- FileInputStream:普通的字节输入流.
- BufferedInputStream: .高效的字节输入流(也叫:字节缓冲输入流)
OutputStream:字节输出流的项层抽象类.
- FileOutputStream:普通的字节输出流.
- BufferedOutputStream:高效的字节输出流(也叫:字节缓冲输出流).
-
字符流:以字符为 单位来操作数据.
Reader:字符输入流的顶层抽象类.- FileReader:普通的字符输入流.
- BufferedReader:高效的字符输入流(也叫:字符缓冲输入流)
Writer:字符输出流的顶层抽象类.
- FileWriter:普通的字符输出流.
- BufferedWriter:高效的字符输出流(也叫:字符缓冲输出流)
-
File类
File类:
文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹
大白话解释:就是用来操作文件(夹)路径的.
构造方法:
File (String pa thname) 根据给定的字符串路径创建其对应File对象.
File(String parent, String child) 根据给定的字符串形式的父目录和子文件(夹)名创建File对象.
File(File parent, String child) 根据给定的父目录对象和子文件(夹)名创建File对象.
成员方法:
创建功能:
createNewFile():创建文件,
mkdir():创建单级目录
mkdirs():创建目录
判断功能:
isDirectory():判断File对象是否为目录
isFile(:判断File对象是 否为文件
exists():判断File对象是否存在
◆成员方法:
getAbsolutePath( ):获取绝对路径
绝对路径:以盘符开头的路径. 例如: D:/1.txt
getPath( :获取文件的相对路径
相对路径: -般是相对于当前项目路径来讲的. 例如: 1.txt
读写文件(具体看视频、文档)
字符流读数据-按单个字符读取
◆创建字符流读文件对象:
Reader reader =new FileReader (" readme. txt") ;
◆调用方法读取数据:
int data = reader. read() ;
读取一个字符,返回该字符代表的整数,若到达流的末尾,返回-1
◆异常处理:
throws IOExcept ion
◆关闭资源:
reader.close();
字符流读数据-按字符数组读取
◆创建字符流读文件对象:
Reader reader = new FileReader (”readme. txt’ )
◆调用方法读取数据:
char[] chs = new char [2048];
int len = r. read (chs) ;
读取字符到数组中,返回读取的字符数,若到达流的末尾,返回-1
◆异常处理:
throws IOException
◆关闭资源:
reader.close();
字符流写数据
Writer类中的方法:
void write(int ch);一次写一个字符
void write(char[] chs, int index, int len);一次写一个指定的字符数组
void write(String str) ;一次写一个字符串
FileWriter类的构造方法:
的顶层抽象类.
- FileReader:普通的字符输入流.
- BufferedReader:高效的字符输入流(也叫:字符缓冲输入流)
Writer:字符输出流的顶层抽象类.
- FileWriter:普通的字符输出流.
- BufferedWriter:高效的字符输出流(也叫:字符缓冲输出流)
File类
File类:
文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹
大白话解释:就是用来操作文件(夹)路径的.
构造方法:
File (String pa thname) 根据给定的字符串路径创建其对应File对象.
File(String parent, String child) 根据给定的字符串形式的父目录和子文件(夹)名创建File对象.
File(File parent, String child) 根据给定的父目录对象和子文件(夹)名创建File对象.
成员方法:
创建功能:
createNewFile():创建文件,
mkdir():创建单级目录
mkdirs():创建目录
判断功能:
isDirectory():判断File对象是否为目录
isFile(:判断File对象是 否为文件
exists():判断File对象是否存在
◆成员方法:
getAbsolutePath( ):获取绝对路径
绝对路径:以盘符开头的路径. 例如: D:/1.txt
getPath( :获取文件的相对路径
相对路径: -般是相对于当前项目路径来讲的. 例如: 1.txt
读写文件(具体看视频、文档)
字符流读数据-按单个字符读取
◆创建字符流读文件对象:
Reader reader =new FileReader (" readme. txt") ;
◆调用方法读取数据:
int data = reader. read() ;
读取一个字符,返回该字符代表的整数,若到达流的末尾,返回-1
◆异常处理:
throws IOExcept ion
◆关闭资源:
reader.close();
字符流读数据-按字符数组读取
◆创建字符流读文件对象:
Reader reader = new FileReader (”readme. txt’ )
◆调用方法读取数据:
char[] chs = new char [2048];
int len = r. read (chs) ;
读取字符到数组中,返回读取的字符数,若到达流的末尾,返回-1
◆异常处理:
throws IOException
◆关闭资源:
reader.close();
字符流写数据
Writer类中的方法:
void write(int ch);一次写一个字符
void write(char[] chs, int index, int len);一次写一个指定的字符数组
void write(String str) ;一次写一个字符串
FileWriter类的构造方法:
public FileWriter (String pathname); 根据传入的字符串形式的路径,获取字符输出流对象