1.1入门
1.1.1 Java是什么
Java是一种面向对象的编程语言
Java特性:
简单性-相对于C、C++,没有指针,有自动垃圾回收
面向对象-Java完全面向对象
高效性-支持多线程
安全性-验证,异常处理
跨平台-一处编译,处处运行,平台就是指操作系统,通过JVM实现。
1.1.2 开发的环境
JDK:Java Development Kit Java开发工具包
提供了开发Java程序必须的编译器、调试器、执行器、Java运行时环境库(JRE)、类库。
- 安装JDK
傻瓜式安装
注意:记住安装在哪个文件夹下了!!
配置环境变量
JAVA_HOME:
配置的是JDK的安装目录
告诉系统以及相关的开发工具(比如Tomcat)JDK安装在电脑的什么位置!
Path:
配置的是JDK的bin目录
系统执行程序的查找路径
验证:
在命令行下,执行java -version
关机再开机后,环境变量失效!!重新修改一次环境变量,然后选择重启!
3HelloWorld
1)在D盘下创建了一个文件夹JavaCode
2)在JavaCode中创建了一个文本文件
3)重命名为HelloWorld.java
4)用记事本打开并输入:
5)打开命令行,切换到D:/JavaCode目录下
6)编译代码:Javac文件名,将源代码编译成字节码文件,HelloWorld.class可以直接在JVM中运行。
7)运行类:Java 类名 在命令行中即可打印出运行结果。
IDE-集成开发环境
Eclipse – 开源免费的,功能很全面,支持各种插件,社区
MyEclipse – 收费
IDEA – 收费的,功能强大,友好,资源消耗大
-
-
- JDK、JRE、JVM
-
JDK:开发Java程序必须的最基本的环境。
开发工具javac、java
类库
JRE:Java运行时 环境——Java程序运行的必要环境
如果不需要开发,只需要运行字节码文件,只要有JRE就可以了
运行时类库 核心库和扩展库
JVM:Java虚拟机,执行Java的字节码程序
WWWH
What:是什么?
Why:为什么?
When:什么时候?
How:怎么玩,用?Java类名
逻辑性
分条
前因后果
1.2基本语法
1.2.1关键字
在Java中已经定义好的具有一定功能和作用的单词。
48个关键字+3个值类型+2个保留字(目前没用,将来可能用)
3个值:true、null、false
2个保留字:goto、const
Java中的关键字全部都是小写的!
class是一个关键字,但Class不是一个关键字
1.2.2标识符
编写Java代码时,定义的一些名字。比如:类名、包名、接口名、枚举名、变量名、常量名、方法名等等。
规则-法律
1)标识符只能由字母、数字、_、$组成
2)不能以数字开头
3)标识符不能使用关键字和保留字
4)严格区分大小写
能不能使用汉字来定义一个标识符??
能!但不要使用!!!!!
规范-道德
- 标识符,应该由具有指定含义的英文单词组成
- 类名、接口名、枚举名应采用大驼峰命名,既每个单词首字母大写,其他字母小写。
- 变量名和方法名采用小驼峰命名法,首单词全部小写,其余每个单词首字母大写。
- 常量、枚举值采用下划线命名法,所有字母全部大写,单词与单词之间使用下划线_分隔。
1.2.3变量和常量
变量:在程序运行过程中,值可以改变的内存空间。
定义:数据类型 变量名
赋值:变量名=值
使用:通过变量名,访问它的值。
注意:
1)变量必须先定义才能使用
2)变量必须先赋值才能使用
3)变量有作用域,声明的{}范围
4)变量不能重复定义
常量:在程序的运行过程中,知不可以改变的内存空间。
定义: final 数据类型 常量名
1.2.4数据类型
- 基本数据类型8种
1字节=8bit(二进制的01)
类型 | 值 | 内存(字节) | 范围 | |
byte | 整数 | 1 | -128~127 | |
short | 2 | -32768~32767 | ||
int | 4 | -21亿~21亿 | ||
long | 8 | - | 赋值时使用L | |
float | 浮点数 | 4 | 赋值时使用F/f | |
double | 8 | |||
char | 字符 | 2 | 表示一个Unicode编码 | 只能表示一个字符用’’ |
boolean | 布尔 | 1 | 只能表示true和false |
注意:在Java中,整数常量值,被默认解析为int类型,小数常量被默认解析为double类型。
- 引用类型
数组
类
接口
- 类型转换
布尔类型不能与其他类型转换,无论强制还是自动!
- 自动类型转换
在基本数据类型中,表示范围小的可以直接复制给表示范围大的数据类型。
byte->short->int->long->float->double
char->int
注意:
- byte和short在运算时会先自动转换成int再进行运算
- 变量在进行赋值时也不能超出他的表示范围
- 为char类型赋值整数时,会当作unicode编码进行赋值,范围0~65535。
- 常量值运算时,会在编译阶段进行,不会等到运行时再运算
- 强制类型转换
范围大的值可以使用强制类型转换符转换为范围小的数据类型。
强制类型转换时可能会导致数据溢出。
1.2.5输入输出
输入:
System.out.print();输出不换行
System.out.println();输出换行
System.err.println();输出错误信息(用红色字体输出)
输出:
Scanner sc =new Scanner(System.in);
sc.next() 采集字符
sc.nextInt() 采集整数
sc.nextFloat() 采集浮点
1.2.6注释
不会执行的,对代码进行解释和说明的文本!!!
- 单行
//单行注释
- 多行
/*
*/多行注释
3)文档 – 生成代码的文档!!!
/**文档注释
*/
1.3运算符和表达式
算式、加减乘除的运算符号
1.3.1算术运算符
1.+
1)数值型的加法运算,数值型(byte,short,int,long,float,double,char)
2)表示正号
3)对字符串进行拼接
2.-
1)数值型减法运算
2)表示符号
3.*
乘法运算
4./
除法运算
整数相除结果还是整数(地板除)
5.%
取余、求余、求模:求除法的余数
- 对负数进行求余,结果的符号由第一个
- 可以对小数进行求余
6.++
自增
7.—
自减
8.前置和后置
前置:先对变量进行自增,再进行运算
后置:先进行运算,再进行自增
1.3.2比较运算符
比较运算符的运算结果是布尔型的
>、<、>=、<=
可以对数值型的进行比较运算。如果成立,结果为布尔类型的true,否则为false
=、!=
- 针对8种基本数据类型,比较值是否相等。
- 针对引用类型String ,比较的是两个引用,是否指向同一块内存地址。
1.3.3逻辑运算符
逻辑运算符只针对布尔类型进行运算,运行结果是布尔类型
1.逻辑与:&&、&
当两个操作数都为真时,结果为true,否则为false
2.逻辑或:||、|
当两个操作数都为false时,结果为false,否则为true。
3.逻辑非:!
当操作数为true时,结果为false,否则为true
单目运算符
!A
4.短路运算
针对&&、||两种逻辑运算
当第一个操作数,已经能够确定运算结果时,第二个操作数不会执行
&&:A&&B如果A=false,结果必然是false,B不再进行运算
||:A||B如果A=true,则结果必然是true,B不再进行运算。
1.3.4位运算符
在二进制的基础上,对数据进行运算
按位与
当两个操作位的对应位都是1,结果的对应位也是1,否则为0
1010&1011 ==1010
3&5 == 011&101 == 001
3&-5?
- 去掉负号-1求二进制;5-1=4 00000100
- 按位取反:11111011
- 3:00000011 5:11111011
- 00000011&11111011 == 00000011
按位或
当两个操作数对应位都是0,结果的对应位就是0,否则为1
1010|1011 == 1011
3|5 == 011|101 == 111
按位异或
^
1010^1011 === 0001
当两个操作数的对应位不同时,结果的对应位是1,否则是0
按位取反
~ 单目运算符
当操作数的对应位为0时,结果的对应位为1,否则为0
~1010 == 0101
左移位
所有的二进制位全部向左移动指定位数,右侧补零,移出去的位不要了
A<<2:A向左移动2位
11001010 << 1 10010100
7 << 2: 111-<00011100
向左移一位相当于*2,移两位相当于*2*2
右移位
>>
所有二进制全部向右移动指定位置,左侧补符号位
11001010>>1 == 01100101
相当于除以2
无符号右移为
>>>
所有二进制位全部向右移,左侧补0
1.3.5赋值运算符
为变量常量赋值操作
=
赋值时需要给变量、常量指定一个类型符合的值
char c = 10
赋值运算符还可以与常见的二目运算符组合成为复合赋值运算符
复合赋值运算符在运算时,会自动对数据类型进行转换
1.3.6三目运算符
A?B:C
A:必须是一个布尔型的值
当A的值时true时,整个表达式的值就是B的值
当A的值是false时,整个表达式的值就是C的值
从右往左结合运算符,从左向右自行代码
1.3.7运算符的优先级
1.4流程控制
控制代码执行的顺序
- 顺序结构
指代码从前往后一行一行的顺序执行
最基本的执行方式
- 分支结构
根据一定的条件进行判定,条件成立时执行一部分代码;不成立时执行另一部分代码。
1.4.1 If…else…
语法:
If(条件表达式){
代码块
}else if{
代码块
}
…
else{
代码块
}}
执行过程
1.4.2 switch…case
语法:switch(表达式){
case 常量一:
代码块
break;
case常量二:
代码块
break;
…
default
}
表达式可以是byte、short、int、char。后期又加入了String、枚举。
执行过程:
- 先计算表达式的值。
- 与第一个case的常量值进行对比
- 如果相等,进入case后的代码块执行,直到遇到break才跳出switch
- 如果不相等,在比较下一个case
- 如果没有任何一个case的常量值相匹配,进入default后的代码块执行
注意:case后的常量值不能重复;进入case后直到遇到break才会结束,如果没有break,可能进入下一个case或default执行
1.4.3 while
语法:
While(条件表达式){
循环体
}
执行过程:
- 执行条件表达式,他也是一个布尔类型的
- 如果条件成立进入循环体执行
- 循环完成后回到第1)步
1.4.4 do…while
语法:
Do{
循环体
}while(条件表达式);
执行顺序:
- 执行循环体
- 循环体执行完成后,判断条件表达式的值
- 如果条件成立,回到1)执行
- 如果条件不成立结束循环
注意:do…while必须以分号结束
while和do while的区别:
- 语法结构:while是条件在前,循环体在后,do while循环体在前条件在后
- 执行顺序:while先条件判断,再执行循环体,do while先执行循环体再进行条件判断
- while的循环体可能一次也不执行,do while的循环体至少执行一次
1.4.5 for
语法:
For(初始化表达式:条件表达式:){
循环体
}
初始化表达式:在for循环执行之前,对循环进行初始化。通常声明循环的迭代变量,并初始化一个值,比如for(int I = 0;…;…)
迭代表达式:每次循环体执行完之后,执行迭代表达式,对循环状态进行控制,通过对迭代变量进行值的改变。
比如 for(int i=0;…;i++)
执行过程:
- 执行初始化表达式
- 判断条件表达式的值
- 如果条件成立,进入循环体执行
- 循环体执行结束后执行迭代表达式
- 迭代表达式执行完之后
1.4.6 特殊循环
1.·嵌套循环
在一个循环中,还包含了另外的循环
- 无限循环
死循环!!!
循环条件永远成立
While(true){
循环体
}
Do {
循环体
}while(true);
for(;true;){
循环体;
}
for (byte i = 0; i < 10; i--) { //byte是有界的,这不是死循环 |
1.4.7 循环控制
1.break
1)用在switch中用来结束switch
2)用在循环中直接结束循环。
2.continue
用在循环中,结束本次循环,直接进入下一次循环
- return
1)结束方法。用在循环中,方法都结束了,循环也会结束
2)为方法提供返回值
1.5方法
1.5.1什么是方法
方法就是一组代码的集合
为了实现代码的复用,相同功能的代码不需要写多次。
1.5.2定义方法
语法:
必须定义在类里面。
修饰符 返回值类型 方法名(参数列表){
方法体
}
- 修饰符
可以有多个
用来限定方法的使用范围和使用方式
范围:权限修饰符(public、protected、默认的、private)
方式:static静态的、abstract抽象的、final最终的、synchronized同步的、native本地的(C、C++编写的方法)。
2.返回值类型
1)void:表示方法没有返回值
2)基本数据类型、引用类型:指定方法的返回值类型,要求方法在结束的每一个出口都要提供想用类型的返回值。
返回值使用return来提供
如果方法没有返回值可以直接使用return来结束方法
3.方法名
方法名是一个标识符
方法名采用小驼峰命名法 第一个单词所有字母全都小写,其余单词首字母大写
- 参数列表
向方法传递数据的载体。
- 没有参数:无参方法()
- 有参数:指定参数的数据类型和参数的名字,多个参数使用逗号分隔。
(数据类型 参数1,数据类型 参数名2)
1.5.3调用方法
1调用
使用方法名+圆括号,如果有参数需要传递参数值
语法:
方法名(参数)
传递的参数,必须与方法定义时的参数数量和类型相匹配。
- 实参和形参
形参:形式参数,方法定义时,参数列表中的参数
实参:实际参数,调用方法时,给他传递的具体的值
将实参的值,赋值给形参,传值调用,Java中所有的方法调用都是传参调用。
1.5.4递归调用
在方法的内部,调用了方法自己
递归通过都可以转换成循环
递归更容易理解,JVM中递归调用不是无限的
循环不如递归容易理解,但他可以无限循环
求1~100的和
操你给小往大了求,先加1,再加2,。。。
加入已经知道了1~99的和这时只需再加上100就可以了。
当递归层数过多时,会出现Java.lang.StackOverflowError.——栈溢出错误/
当方法被调用时,方法将汇入栈。栈是一块内存,有限的。
1.5.5重载
1.概念:
在一个类中,出现了方法名相同但是参数列表不同的方法,这就叫重载
2.调用:
调用重载方法是=时,根据实参的数据类型,寻找最为匹配的方法进行调用。
- 重载的需求
参数列表不同
- 参数的数量不同
- 参数的类型不同
- 参数的顺序不同
不构成重载:
- 参数名不同
- 返回值类型不同
1.6数组
1.6.1数组的概念和特点
数组是一个可以保存多个相同类型元素的集合。
特点:
- 内存连续。数组中的元素在内存中都是紧紧挨着的
有序性-元素的前后顺序。
- 大小固定。数组一旦创建大小就不能改变了
1.6.2数组的定义
数组本质上是一种数据类型。
1.方式一
语法:
数据类型[] 数组名;
- 方式二
语法:
数据类型 数组名[];
1.6.3数组的初始化
1.动态初始化
语法:
数组名=new 数据类型[长度];
New:为一个对象分配配内存空间。
数据类型:数组定义时的数据类型一致
长度:数组中可以保存的元素的数量
可以通过类型的长度,计算他的内存空间。
动态初始化时,会为数组中的每个元素提供一个类0的初始值
数据类型 | 类0值 |
byte | 0 |
short | 0 |
Int | 0 |
long | 0 |
float | 0.0f |
double | 0.0 |
Char | 0对应的字符 |
boolean | false |
引用 | null |
变量总是放在栈里面
基本类型的变量保存的具体的值
引用类型的变量,保存的是对象的引用,对象的地址
2.静态初始化
语法:
数组名 = new 数据类型[]{元素1,元素2,元素3}
数组长度由{}中的元素数量决定
数组中的每一个元素,都会被初始化为{}中滴哦应位置的元素
简写形式:
数据类型[] 数组名 = {元素1,元素2,怨怒3…}
1.6.4元素的访问
语法:
数组名[下标]
下标就是元素在数组中的位置
下标的取值:0~长度-1
ArrayIndexOutOfBoundsException
1.6.5数组的操作
1.循环赋值
循环生成下标
2.遍历
1)循环生成下标
2)增强for循环 foerach
语法:
for(数据类型 变量名:集合){
循环体
}
执行过程:
- 尝试从集合中取出一个元素
- 如果成功取出一个元素,将元素赋值给变量。执行循环体。
- 在循环体中,可以使用变量访问元素的值。
- 循环体执行完之后,回到第1)步。
- 如果无法取出一个元素,说明集合中的元素都已经被取过一次,此时循环结束
- 求最值
假设法
- 求和、平均值
- 查找元素位置
查找存在
查找不存在
查找第一个
查找最后一个
时间复杂度:对程序时间上的衡量O(1) O(n) o(n^2) O(logn)
空间复杂度:对程序内存空间上的衡量O(1) O(n) o(n^2) O(logn)
遍历的方式查找元素:时间复杂度就是O(n);
1.6.6二分查找算法
折半查找
时间复杂度:O(logn)
前提:数组中的元素必须是已经根据它的大小排好顺序
思想:
在一个有序(升序)数组中,先与数组的中间元素进行比较。
- 查找元素 = 中间元素:找到了!!
- 查找元素 < 中间元素:如果有,肯定在中间元素的前面
- 查找元素 > 中间元素:如果有,肯定在中间元素的后面
- 继续使用二分查找,查找元素的具体位置
1.6.7数组的排序
将一个无序的数组,按照指定的规则调整元素的位置,使之变得有序
十大排序算法:
序号 | 算法 | 时间复杂度 | 稳不稳定 | 学习程度 |
1 | 冒泡排序 | O(n^2) | 稳定 | 思想+代码 |
2 | 选择排序 | 不稳定 | 思想+代码 | |
3 | 插入排序 | 稳定 | 思想+代码 | |
4 | 快速排序 | O(nlogn) | 不稳定 | 思想+代码 |
5 | 希尔排序 | 不稳定 | 了解复杂度(插入排序的改进) | |
6 | 归并排序 | 稳定 | 了解复杂度 | |
7 | 堆排序 | 不稳定 | 了解复杂度 | |
8 | 计数排序 | O(n) | 稳定 | 了解复杂度 |
9 | 桶排序 | 稳定 | 了解复杂度 | |
10 | 基数排序 | 稳定 | 了解复杂度 |
1.冒泡排序:
相邻相比较,大的往后靠
- 将数组中相邻的元素进行比较,将较大的元素放在后面。
arr[i]>arr[i+1]:交换两个元素的位置
最大的元素将会移动到数组的最后面
- 针对前面未排好序的部分,重复第一步直到数组排序完成
2.选择排序
1)找到数组最大值,放到数组最后面。
2)缩小排序范围,重新1)步
3.插入排序
思想:先从最小的干
- 将数组中的第一个元素看作是一个有序数组
- 在数组中增加一个元素,并且将它插入到一个合适的位置。
- 依次类推
希尔排序是插入排序的改进
- 快速排序
1)先找一个元素,作为基准元素,通常找第一个(下标为0).
2)将所有比基准元素小的放到前面,大的放到后面。
3)基准元素将数组分成两个部分,再对这两个小的数组分别进行快排序
1.6.8 多维数组
1.定义
变量定义:数据类型 变量名;
数组定义:数据类型[] 数组名;
数组也是数据类型,定义数组时,数据类型是不是也可以是也可以是一个数组?
数据类型[][] 数组名;
二维数组定义语法:
数据类型[] [] 数组名;
数据类型[] 数组名[];
数据类型 数组名[] [];
2.二维数组
数据类型[][]数组名;
二维数组可以看作是一个特殊的一维2数组,它的每一个元素是一个一维数组。
3.初始化
1)动态初始化
数据类型[][] 数组名 = new 数据类型[一维长度] [二维长度];
2)静态初始化
数组名 = new 数据类型[][] {{元素1,元素2},{1,2},{3,5}};
访问元素
值:0~长度-1
NullPointerException
操作
- 遍历 一层层遍历
循环生成下标志
Foreach
- 最值
- 求和
- 查找
- 排序
1.6.9Arrays类
这是一个工具类,由JDK提供
主要提供了对数组的常用操作。
sort;
binarySearch
copyOf
copyfRange
equals
1.1入门
1.1.1 Java是什么
Java是一种面向对象的编程语言
Java特性:
简单性-相对于C、C++,没有指针,有自动垃圾回收
面向对象-Java完全面向对象
高效性-支持多线程
安全性-验证,异常处理
跨平台-一处编译,处处运行,平台就是指操作系统,通过JVM实现。
1.1.2 开发的环境
JDK:Java Development Kit Java开发工具包
提供了开发Java程序必须的编译器、调试器、执行器、Java运行时环境库(JRE)、类库。
- 安装JDK
傻瓜式安装
注意:记住安装在哪个文件夹下了!!
配置环境变量
JAVA_HOME:
配置的是JDK的安装目录
告诉系统以及相关的开发工具(比如Tomcat)JDK安装在电脑的什么位置!
Path:
配置的是JDK的bin目录
系统执行程序的查找路径
验证:
在命令行下,执行java -version
关机再开机后,环境变量失效!!重新修改一次环境变量,然后选择重启!
3HelloWorld
1)在D盘下创建了一个文件夹JavaCode
2)在JavaCode中创建了一个文本文件
3)重命名为HelloWorld.java
4)用记事本打开并输入:
5)打开命令行,切换到D:/JavaCode目录下
6)编译代码:Javac文件名,将源代码编译成字节码文件,HelloWorld.class可以直接在JVM中运行。
7)运行类:Java 类名 在命令行中即可打印出运行结果。
IDE-集成开发环境
Eclipse – 开源免费的,功能很全面,支持各种插件,社区
MyEclipse – 收费
IDEA – 收费的,功能强大,友好,资源消耗大
-
-
- JDK、JRE、JVM
-
JDK:开发Java程序必须的最基本的环境。
开发工具javac、java
类库
JRE:Java运行时 环境——Java程序运行的必要环境
如果不需要开发,只需要运行字节码文件,只要有JRE就可以了
运行时类库 核心库和扩展库
JVM:Java虚拟机,执行Java的字节码程序
WWWH
What:是什么?
Why:为什么?
When:什么时候?
How:怎么玩,用?Java类名
逻辑性
分条
前因后果
1.2基本语法
1.2.1关键字
在Java中已经定义好的具有一定功能和作用的单词。
48个关键字+3个值类型+2个保留字(目前没用,将来可能用)
3个值:true、null、false
2个保留字:goto、const
Java中的关键字全部都是小写的!
class是一个关键字,但Class不是一个关键字
1.2.2标识符
编写Java代码时,定义的一些名字。比如:类名、包名、接口名、枚举名、变量名、常量名、方法名等等。
规则-法律
1)标识符只能由字母、数字、_、$组成
2)不能以数字开头
3)标识符不能使用关键字和保留字
4)严格区分大小写
能不能使用汉字来定义一个标识符??
能!但不要使用!!!!!
规范-道德
- 标识符,应该由具有指定含义的英文单词组成
- 类名、接口名、枚举名应采用大驼峰命名,既每个单词首字母大写,其他字母小写。
- 变量名和方法名采用小驼峰命名法,首单词全部小写,其余每个单词首字母大写。
- 常量、枚举值采用下划线命名法,所有字母全部大写,单词与单词之间使用下划线_分隔。
1.2.3变量和常量
变量:在程序运行过程中,值可以改变的内存空间。
定义:数据类型 变量名
赋值:变量名=值
使用:通过变量名,访问它的值。
注意:
1)变量必须先定义才能使用
2)变量必须先赋值才能使用
3)变量有作用域,声明的{}范围
4)变量不能重复定义
常量:在程序的运行过程中,知不可以改变的内存空间。
定义: final 数据类型 常量名
1.2.4数据类型
- 基本数据类型8种
1字节=8bit(二进制的01)
类型 | 值 | 内存(字节) | 范围 | |
byte | 整数 | 1 | -128~127 | |
short | 2 | -32768~32767 | ||
int | 4 | -21亿~21亿 | ||
long | 8 | - | 赋值时使用L | |
float | 浮点数 | 4 | 赋值时使用F/f | |
double | 8 | |||
char | 字符 | 2 | 表示一个Unicode编码 | 只能表示一个字符用’’ |
boolean | 布尔 | 1 | 只能表示true和false |
注意:在Java中,整数常量值,被默认解析为int类型,小数常量被默认解析为double类型。
- 引用类型
数组
类
接口
- 类型转换
布尔类型不能与其他类型转换,无论强制还是自动!
- 自动类型转换
在基本数据类型中,表示范围小的可以直接复制给表示范围大的数据类型。
byte->short->int->long->float->double
char->int
注意:
- byte和short在运算时会先自动转换成int再进行运算
- 变量在进行赋值时也不能超出他的表示范围
- 为char类型赋值整数时,会当作unicode编码进行赋值,范围0~65535。
- 常量值运算时,会在编译阶段进行,不会等到运行时再运算
- 强制类型转换
范围大的值可以使用强制类型转换符转换为范围小的数据类型。
强制类型转换时可能会导致数据溢出。
1.2.5输入输出
输入:
System.out.print();输出不换行
System.out.println();输出换行
System.err.println();输出错误信息(用红色字体输出)
输出:
Scanner sc =new Scanner(System.in);
sc.next() 采集字符
sc.nextInt() 采集整数
sc.nextFloat() 采集浮点
1.2.6注释
不会执行的,对代码进行解释和说明的文本!!!
- 单行
//单行注释
- 多行
/*
*/多行注释
3)文档 – 生成代码的文档!!!
/**文档注释
*/
1.3运算符和表达式
算式、加减乘除的运算符号
1.3.1算术运算符
1.+
1)数值型的加法运算,数值型(byte,short,int,long,float,double,char)
2)表示正号
3)对字符串进行拼接
2.-
1)数值型减法运算
2)表示符号
3.*
乘法运算
4./
除法运算
整数相除结果还是整数(地板除)
5.%
取余、求余、求模:求除法的余数
- 对负数进行求余,结果的符号由第一个
- 可以对小数进行求余
6.++
自增
7.—
自减
8.前置和后置
前置:先对变量进行自增,再进行运算
后置:先进行运算,再进行自增
1.3.2比较运算符
比较运算符的运算结果是布尔型的
>、<、>=、<=
可以对数值型的进行比较运算。如果成立,结果为布尔类型的true,否则为false
=、!=
- 针对8种基本数据类型,比较值是否相等。
- 针对引用类型String ,比较的是两个引用,是否指向同一块内存地址。
1.3.3逻辑运算符
逻辑运算符只针对布尔类型进行运算,运行结果是布尔类型
1.逻辑与:&&、&
当两个操作数都为真时,结果为true,否则为false
2.逻辑或:||、|
当两个操作数都为false时,结果为false,否则为true。
3.逻辑非:!
当操作数为true时,结果为false,否则为true
单目运算符
!A
4.短路运算
针对&&、||两种逻辑运算
当第一个操作数,已经能够确定运算结果时,第二个操作数不会执行
&&:A&&B如果A=false,结果必然是false,B不再进行运算
||:A||B如果A=true,则结果必然是true,B不再进行运算。
1.3.4位运算符
在二进制的基础上,对数据进行运算
按位与
当两个操作位的对应位都是1,结果的对应位也是1,否则为0
1010&1011 ==1010
3&5 == 011&101 == 001
3&-5?
- 去掉负号-1求二进制;5-1=4 00000100
- 按位取反:11111011
- 3:00000011 5:11111011
- 00000011&11111011 == 00000011
按位或
当两个操作数对应位都是0,结果的对应位就是0,否则为1
1010|1011 == 1011
3|5 == 011|101 == 111
按位异或
^
1010^1011 === 0001
当两个操作数的对应位不同时,结果的对应位是1,否则是0
按位取反
~ 单目运算符
当操作数的对应位为0时,结果的对应位为1,否则为0
~1010 == 0101
左移位
所有的二进制位全部向左移动指定位数,右侧补零,移出去的位不要了
A<<2:A向左移动2位
11001010 << 1 10010100
7 << 2: 111-<00011100
向左移一位相当于*2,移两位相当于*2*2
右移位
>>
所有二进制全部向右移动指定位置,左侧补符号位
11001010>>1 == 01100101
相当于除以2
无符号右移为
>>>
所有二进制位全部向右移,左侧补0
1.3.5赋值运算符
为变量常量赋值操作
=
赋值时需要给变量、常量指定一个类型符合的值
char c = 10
赋值运算符还可以与常见的二目运算符组合成为复合赋值运算符
复合赋值运算符在运算时,会自动对数据类型进行转换
1.3.6三目运算符
A?B:C
A:必须是一个布尔型的值
当A的值时true时,整个表达式的值就是B的值
当A的值是false时,整个表达式的值就是C的值
从右往左结合运算符,从左向右自行代码
1.3.7运算符的优先级
1.4流程控制
控制代码执行的顺序
- 顺序结构
指代码从前往后一行一行的顺序执行
最基本的执行方式
- 分支结构
根据一定的条件进行判定,条件成立时执行一部分代码;不成立时执行另一部分代码。
1.4.1 If…else…
语法:
If(条件表达式){
代码块
}else if{
代码块
}
…
else{
代码块
}}
执行过程
1.4.2 switch…case
语法:switch(表达式){
case 常量一:
代码块
break;
case常量二:
代码块
break;
…
default
}
表达式可以是byte、short、int、char。后期又加入了String、枚举。
执行过程:
- 先计算表达式的值。
- 与第一个case的常量值进行对比
- 如果相等,进入case后的代码块执行,直到遇到break才跳出switch
- 如果不相等,在比较下一个case
- 如果没有任何一个case的常量值相匹配,进入default后的代码块执行
注意:case后的常量值不能重复;进入case后直到遇到break才会结束,如果没有break,可能进入下一个case或default执行
1.4.3 while
语法:
While(条件表达式){
循环体
}
执行过程:
- 执行条件表达式,他也是一个布尔类型的
- 如果条件成立进入循环体执行
- 循环完成后回到第1)步
1.4.4 do…while
语法:
Do{
循环体
}while(条件表达式);
执行顺序:
- 执行循环体
- 循环体执行完成后,判断条件表达式的值
- 如果条件成立,回到1)执行
- 如果条件不成立结束循环
注意:do…while必须以分号结束
while和do while的区别:
- 语法结构:while是条件在前,循环体在后,do while循环体在前条件在后
- 执行顺序:while先条件判断,再执行循环体,do while先执行循环体再进行条件判断
- while的循环体可能一次也不执行,do while的循环体至少执行一次
1.4.5 for
语法:
For(初始化表达式:条件表达式:){
循环体
}
初始化表达式:在for循环执行之前,对循环进行初始化。通常声明循环的迭代变量,并初始化一个值,比如for(int I = 0;…;…)
迭代表达式:每次循环体执行完之后,执行迭代表达式,对循环状态进行控制,通过对迭代变量进行值的改变。
比如 for(int i=0;…;i++)
执行过程:
- 执行初始化表达式
- 判断条件表达式的值
- 如果条件成立,进入循环体执行
- 循环体执行结束后执行迭代表达式
- 迭代表达式执行完之后
1.4.6 特殊循环
1.·嵌套循环
在一个循环中,还包含了另外的循环
- 无限循环
死循环!!!
循环条件永远成立
While(true){
循环体
}
Do {
循环体
}while(true);
for(;true;){
循环体;
}
for (byte i = 0; i < 10; i--) { //byte是有界的,这不是死循环 |
1.4.7 循环控制
1.break
1)用在switch中用来结束switch
2)用在循环中直接结束循环。
2.continue
用在循环中,结束本次循环,直接进入下一次循环
- return
1)结束方法。用在循环中,方法都结束了,循环也会结束
2)为方法提供返回值
1.5方法
1.5.1什么是方法
方法就是一组代码的集合
为了实现代码的复用,相同功能的代码不需要写多次。
1.5.2定义方法
语法:
必须定义在类里面。
修饰符 返回值类型 方法名(参数列表){
方法体
}
- 修饰符
可以有多个
用来限定方法的使用范围和使用方式
范围:权限修饰符(public、protected、默认的、private)
方式:static静态的、abstract抽象的、final最终的、synchronized同步的、native本地的(C、C++编写的方法)。
2.返回值类型
1)void:表示方法没有返回值
2)基本数据类型、引用类型:指定方法的返回值类型,要求方法在结束的每一个出口都要提供想用类型的返回值。
返回值使用return来提供
如果方法没有返回值可以直接使用return来结束方法
3.方法名
方法名是一个标识符
方法名采用小驼峰命名法 第一个单词所有字母全都小写,其余单词首字母大写
- 参数列表
向方法传递数据的载体。
- 没有参数:无参方法()
- 有参数:指定参数的数据类型和参数的名字,多个参数使用逗号分隔。
(数据类型 参数1,数据类型 参数名2)
1.5.3调用方法
1调用
使用方法名+圆括号,如果有参数需要传递参数值
语法:
方法名(参数)
传递的参数,必须与方法定义时的参数数量和类型相匹配。
- 实参和形参
形参:形式参数,方法定义时,参数列表中的参数
实参:实际参数,调用方法时,给他传递的具体的值
将实参的值,赋值给形参,传值调用,Java中所有的方法调用都是传参调用。
1.5.4递归调用
在方法的内部,调用了方法自己
递归通过都可以转换成循环
递归更容易理解,JVM中递归调用不是无限的
循环不如递归容易理解,但他可以无限循环
求1~100的和
操你给小往大了求,先加1,再加2,。。。
加入已经知道了1~99的和这时只需再加上100就可以了。
当递归层数过多时,会出现Java.lang.StackOverflowError.——栈溢出错误/
当方法被调用时,方法将汇入栈。栈是一块内存,有限的。
1.5.5重载
1.概念:
在一个类中,出现了方法名相同但是参数列表不同的方法,这就叫重载
2.调用:
调用重载方法是=时,根据实参的数据类型,寻找最为匹配的方法进行调用。
- 重载的需求
参数列表不同
- 参数的数量不同
- 参数的类型不同
- 参数的顺序不同
不构成重载:
- 参数名不同
- 返回值类型不同
1.6数组
1.6.1数组的概念和特点
数组是一个可以保存多个相同类型元素的集合。
特点:
- 内存连续。数组中的元素在内存中都是紧紧挨着的
有序性-元素的前后顺序。
- 大小固定。数组一旦创建大小就不能改变了
1.6.2数组的定义
数组本质上是一种数据类型。
1.方式一
语法:
数据类型[] 数组名;
- 方式二
语法:
数据类型 数组名[];
1.6.3数组的初始化
1.动态初始化
语法:
数组名=new 数据类型[长度];
New:为一个对象分配配内存空间。
数据类型:数组定义时的数据类型一致
长度:数组中可以保存的元素的数量
可以通过类型的长度,计算他的内存空间。
动态初始化时,会为数组中的每个元素提供一个类0的初始值
数据类型 | 类0值 |
byte | 0 |
short | 0 |
Int | 0 |
long | 0 |
float | 0.0f |
double | 0.0 |
Char | 0对应的字符 |
boolean | false |
引用 | null |
变量总是放在栈里面
基本类型的变量保存的具体的值
引用类型的变量,保存的是对象的引用,对象的地址
2.静态初始化
语法:
数组名 = new 数据类型[]{元素1,元素2,元素3}
数组长度由{}中的元素数量决定
数组中的每一个元素,都会被初始化为{}中滴哦应位置的元素
简写形式:
数据类型[] 数组名 = {元素1,元素2,怨怒3…}
1.6.4元素的访问
语法:
数组名[下标]
下标就是元素在数组中的位置
下标的取值:0~长度-1
ArrayIndexOutOfBoundsException
1.6.5数组的操作
1.循环赋值
循环生成下标
2.遍历
1)循环生成下标
2)增强for循环 foerach
语法:
for(数据类型 变量名:集合){
循环体
}
执行过程:
- 尝试从集合中取出一个元素
- 如果成功取出一个元素,将元素赋值给变量。执行循环体。
- 在循环体中,可以使用变量访问元素的值。
- 循环体执行完之后,回到第1)步。
- 如果无法取出一个元素,说明集合中的元素都已经被取过一次,此时循环结束
- 求最值
假设法
- 求和、平均值
- 查找元素位置
查找存在
查找不存在
查找第一个
查找最后一个
时间复杂度:对程序时间上的衡量O(1) O(n) o(n^2) O(logn)
空间复杂度:对程序内存空间上的衡量O(1) O(n) o(n^2) O(logn)
遍历的方式查找元素:时间复杂度就是O(n);
1.6.6二分查找算法
折半查找
时间复杂度:O(logn)
前提:数组中的元素必须是已经根据它的大小排好顺序
思想:
在一个有序(升序)数组中,先与数组的中间元素进行比较。
- 查找元素 = 中间元素:找到了!!
- 查找元素 < 中间元素:如果有,肯定在中间元素的前面
- 查找元素 > 中间元素:如果有,肯定在中间元素的后面
- 继续使用二分查找,查找元素的具体位置
1.6.7数组的排序
将一个无序的数组,按照指定的规则调整元素的位置,使之变得有序
十大排序算法:
序号 | 算法 | 时间复杂度 | 稳不稳定 | 学习程度 |
1 | 冒泡排序 | O(n^2) | 稳定 | 思想+代码 |
2 | 选择排序 | 不稳定 | 思想+代码 | |
3 | 插入排序 | 稳定 | 思想+代码 | |
4 | 快速排序 | O(nlogn) | 不稳定 | 思想+代码 |
5 | 希尔排序 | 不稳定 | 了解复杂度(插入排序的改进) | |
6 | 归并排序 | 稳定 | 了解复杂度 | |
7 | 堆排序 | 不稳定 | 了解复杂度 | |
8 | 计数排序 | O(n) | 稳定 | 了解复杂度 |
9 | 桶排序 | 稳定 | 了解复杂度 | |
10 | 基数排序 | 稳定 | 了解复杂度 |
1.冒泡排序:
相邻相比较,大的往后靠
- 将数组中相邻的元素进行比较,将较大的元素放在后面。
arr[i]>arr[i+1]:交换两个元素的位置
最大的元素将会移动到数组的最后面
- 针对前面未排好序的部分,重复第一步直到数组排序完成
2.选择排序
1)找到数组最大值,放到数组最后面。
2)缩小排序范围,重新1)步
3.插入排序
思想:先从最小的干
- 将数组中的第一个元素看作是一个有序数组
- 在数组中增加一个元素,并且将它插入到一个合适的位置。
- 依次类推
希尔排序是插入排序的改进
- 快速排序
1)先找一个元素,作为基准元素,通常找第一个(下标为0).
2)将所有比基准元素小的放到前面,大的放到后面。
3)基准元素将数组分成两个部分,再对这两个小的数组分别进行快排序
1.6.8 多维数组
1.定义
变量定义:数据类型 变量名;
数组定义:数据类型[] 数组名;
数组也是数据类型,定义数组时,数据类型是不是也可以是也可以是一个数组?
数据类型[][] 数组名;
二维数组定义语法:
数据类型[] [] 数组名;
数据类型[] 数组名[];
数据类型 数组名[] [];
2.二维数组
数据类型[][]数组名;
二维数组可以看作是一个特殊的一维2数组,它的每一个元素是一个一维数组。
3.初始化
1)动态初始化
数据类型[][] 数组名 = new 数据类型[一维长度] [二维长度];
2)静态初始化
数组名 = new 数据类型[][] {{元素1,元素2},{1,2},{3,5}};
访问元素
值:0~长度-1
NullPointerException
操作
- 遍历 一层层遍历
循环生成下标志
Foreach
- 最值
- 求和
- 查找
- 排序
1.6.9Arrays类
这是一个工具类,由JDK提供
主要提供了对数组的常用操作。
sort;
binarySearch
copyOf
copyfRange
equ