卸载JDK
- 通过环境变量设置找到java目录 并删除(JAVA_HOME)
- 删除环境变量设置中的java_home
- 删除环境变量path下的java
- 通过"cmd"运行java -version 命令查看是否存在java命令
安装JDK
- JKD8官方下载
- 找到对应电脑对应的版本
- 双击安装JDK
- 安装路径建议自定义
- 记住安装路径
- 配置环境变量
- 环境变量–>系统变量–>新建–>变量名(JAVA_HOME)–>变量值(JAVA安装目录)
- 环境变量–>系统变量–>path–>双击–>新建–>%JAVA_HOME%\bin(%代表引用意思)–>新建–>%JAVA_HOME%\jre\bin(%代表引用意思)
- 通过"CMD" 运行java -version
notepad++
helloworld
-
新建一个文件夹,存放代码
-
新建一个java文件
- 文件后缀名为.java
- Hello.java
-
编写代码
public class Hello{ public static void main(String[] args){ System.out.print("Hello,World"); } }
-
编译javac java文件,会生成一个class文件
-
运行class文件,java class文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fg9dssqB-1628503217414)(java基础.assets/image-20210714135434697.png)]
可能会出现的问题
-
每个单词的大小写不能出现问题,JAVA是大小写敏感的
-
尽量使用英文
-
文件名和类名必须保证一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CvgJW79g-1628503217418)(java基础.assets/image-20210714135901900.png)]
-
注意符号不要是中文的
JAVA基础
类型转换
-
由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换
低 ---------------------------------------------> 高 byte,short,char -> int -> long -> float -> double
-
运算中,不同类型的数据先转化为同一类型,然后进行运算。 低类型往高类型转换
-
强制类型转换
public class Demo02 {
public static void main(String[] args) {
int i = 128;
byte b = (byte)i; // 内存溢出 导致输出结果为负数
byte d = i;
// 强制转换 (类型)变量名 高-->低
// 自动转换 低-->高
System.out.println(i);
System.out.println(b);
System.out.println(d);
}
}
注意点:
- 不能对布尔值转换
- 不能把对象类型转换为不相干的类型
- 把高容量转换为低容量时候,强制转换
- 转换时出现内存溢出或者精度问题 System.out.println((int)23.7) 结果 23
- 自动类型转换
public class Demo03 {
public static void main(String[] args) {
// 数字之间可以用下划线分割
int money = 10_0000_0000;
System.out.println(money);
// 解决溢出问题 可在计算时的变量名前加类型
}
}
变量
变量是什么:就是变化的量
Java是强类型语言,每个变量都必须声明其类型
Java变量是程序中最基本存储单元,要素包括变量名,变量类型和作用域
typy varName [=value] [{,varName[=value]}];
// 数据类型 变量名 = 值;可以使用逗号隔开来声明多个同类型变量。
注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,因此每一个声明都必须已分号结束
public class Demo04 {
public static void main(String[] args) {
// 程序可读性,不建议定义变量写在一行
int a = 1;
int b = 2;
int c = 3;
String name = "qinjiang";
char x = "X";
double pi = 3.14;
}
}
变量作用域
- 类变量
- 实例变量
- 局部变量
public class Variable{
static int allClicks=0; //类变量 关键词static
String str = "Hello,World"; //实例变量
public void method(){
int i = 0; //局部变量
}
}
public class Demo05 {
// 类变量 static
static double salary = 2500;
// 属性 变量
// 实例变量 从属于对象 如果不初始化,这个类型默认值为0 0.0 布尔值默认false 除了基本类型,其余默认值为null
String name;
int age;
// main 方法
public static void main(String[] args){
// 局部变量 必须声明和初始化值
int i = 10;
Demo05 demo05 = new Demo05();
System.out.println(demo05.age);
System.out.println(salary);
}
常量
常量(Constant):初始化(initialize)后不能再改变的值
所谓常量可以理解成一种特殊变量,它的值被设定后,在程序中不允许被改变
final 常量名 = 值final double PI = 3.14;
常量名一般使用大写字符
public class Demo06 { // 修饰符,不存在先后顺序 fanal static static final 都可以 static final double PI = 3.14; public static void main(String[] args) { System.out.println(PI); }}
变量的命名规范
- 所有变量、方法、类名:见名知意
- 类成员变量:首字母小写和驼峰原则 monthSalary
- 局部变量:首字母小写和驼峰
- 常量:大写字母和下划线:MAX_VALUE
- 类名:首字母大写和驼峰原则 Man,GoodMan
- 方法名:首字母小写和驼峰原则 run(),runRun()
运算符
Java语言支持如下运算符:
- 算术运算符:+,-,*,/ ,%,++,–
- 赋值运算符:=
- 关系运算符:>,<,>=,<=,==,!= instanceof
- 逻辑运算符:&&,||,! 与 或 非
- 位运算符:&,|,^,~,>>,<<,>>>(了解!!!)
- 条件运算符
- 扩展赋值运算符:+=,-=,*=,/=
// 算术运算
public class Demo01 {
public static void main(String[] args) {
// 二元运算符
int a = 10;
int b = 20;
int c = 25;
int d = 25;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println((double) a/b);
}
}
// 算术拓展
public class Demo02 {
public static void main(String[] args) {
long a = 121221312313L;
int b = 123;
short c =10;
byte d = 8;
System.out.println(a+b+c+d); //long
System.out.println(b+c+d); // int
System.out.println(c+d); // int
}
}
// 关系运算
public class Demo03 {
public static void main(String[] args) {
// 关系运算符返回结果 正确 错误 布尔值
int a =10;
int b =20;
int c =21;
System.out.println(c%a);
System.out.println(a==b);
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a!=b);
}
}
// 算术运算-自增自减及运算工具类
public class Demo04 {
public static void main(String[] args) {
// ++ -- 自增 自减 一元运算符
int a = 3;
int b = a++; // 先给B 赋值 在自己+1 相当于在b 的下一行执行一个 a=a+1
int c = ++a; // 执行这行代码前 先自增 再给C 赋值 相当于在c赋值前一行执行 a = a+1
System.out.println(a);
System.out.println(b);
System.out.println(b);
System.out.println(c);
System.out.println(c);
// 幂运算 2^3 很多运算我们会采用工具类来操作!
double pow = Math.pow(2,3);
System.out.println(pow);
}
}
包机制
- 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
- 包语句的语法格式为:
package pkg1[.pkg2[.pkg3...]];
- 一般利用公司域名倒置作为包名;
- 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用import语句可完成此功能
import package1[.package2...].(classname|*);
JavaDoc
Javadoc命令是用来生成自己API文档的
- 参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的jdk版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
package operator;/** * @author singk * @version 1.0 * @since 1.8 */public class Demo08 { String name; /** * @author singk * @param name * @return */ public String test (String name) throws Exception{ return name; }}
javadoc -endcoding UTF-8 -charset UTF-8 DOC.java
命令行生成JavaDoc文档
@author 作者
@version 版本号
@param 参数名 描述 方法的入参名及描述信息,如入参有特别要求,可在此注释。
@return 描述 对函数返回值的注释
@deprecated 过期文本 标识随着程序版本的提升,当前API已经过期,仅为了保证兼容性依然存在,以此告之开发者不应再用这个API。
@throws异常类名 构造函数或方法所会抛出的异常。
@exception 异常类名 同@throws。
@see 引用 查看相关内容,如类、方法、变量等。
@since 描述文本 API在什么程序的什么版本后开发支持。
{@link包.类#成员 标签} 链接到某个特定的成员对应的文档中。
{@value} 当对常量进行注释时,如果想将其值包含在文档中,则通过该标签来引用常量的值。
学会用IDEA生成JavaDoc文档 面向百度编程 学会用百度查询问题!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SWhTOzZ1-1628503217421)(java基础.assets/image-20210727174811793.png)]
Java流程控制
用户交互Scanner
Scanner对象
Java提供这样一个工具类,java.util.Scanner 来获取用户的输入
基本语法
Scanner s = new Scanner(System.in);
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据
- next():
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
- 只有输入有效字符后才将其后面输入的空白作为分隔符或结束符。
- next()不能得到带有空格的字符串。
- nextLine():
- 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
- 可以获得空白
示例1:
package Scanner;import java.util.Scanner;public class Demo01 { public static void main(String[] args) { // 创建一个扫描对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("使用next方式接收:"); // 判断用户有没有输入字符串 if (scanner.hasNext()){ //使用next方式接收 String str = scanner.next(); //程序会等待用户输入完毕 System.out.println("输出的内容为:"+str); } // 凡是属于IO流的类如果不关闭会一直占用资源,要养成用完关闭好习惯 scanner.close(); }}
示例2:
package Scanner;import java.util.Scanner;public class Demo02 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("使用nextLine方式接收:"); if (scanner.hasNextLine()){ String str = scanner.nextLine(); System.out.println("输出的内容为:"+str); } scanner.close(); }}
示例3:
package Scanner;import java.util.Scanner;public class Demo03 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入数据:"); String str = scanner.nextLine(); System.out.println("输出结果为:"+str); scanner.close(); }}
示例4:
package Scanner;
import java.util.Scanner;
public class Demo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i = 0;
float f = 0.0f;
System.out.println("请输入整数:");
if (scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据"+i);
}else {
System.out.println("输入不是整数数据!");
}
System.out.println("请输入小数:");
if (scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+f);
}else {
System.out.println("输入的不是小数数据!");
}
}
}
示例5:
package Scanner;
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
// 我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果;
Scanner scanner = new Scanner(System.in);
// 求和
double sum = 0;
// 统计输入数字数量
int m = 0;
// 通过循环判断是否还有输入,并在里面对每一次求和统计
while (scanner.hasNextDouble()){
double x = scanner.nextDouble();
m = m + 1; // m++
sum = sum + x;
}
System.out.println(m+"个数的和为:"+sum);
System.out.println(m+"个数的平均值:"+(sum/m));
scanner.close();
}
}
顺序结构
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
顺序结构是最简单的算法结构
语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。
选择结构
if单选结构
我们很多时候需要去判断一个东西是否可行,然后我们去执行,这样一个过程在程序中用if语句来表示
语法:
if (布尔表达式){ // 如果布尔表达式为true将执行的语句}
示例
package struct;import java.util.Scanner;public class IfDemo01 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入内容:"); String s = scanner.nextLine(); if (s.equals("Hello")){ System.out.println("s"); } System.out.println("End"); scanner.close(); }}
if双选择结构
条件满足则执行语句A,条件不满足则执行语句B。
语法:
if (布尔表达式){ //如果布尔表达式值为true}else{ //如果布尔表达式值为false}
示例
package struct;import java.util.Scanner;public class IfDemo02 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入成绩:"); int score = scanner.nextInt(); if (score>60){ System.out.println("及格"); }else{ System.out.println("不及格"); } scanner.close(); }}
if多选择结构
语法:
if (布尔表达式1){ // 如果布尔表达式1的值为true执行代码}else if(布尔表达式2){ // 如果布尔表达式2的值为true执行代码}else if(布尔表达式3){ // 如果布尔表达式3的值为true执行代码}else{ //以上都不为true}
- if 语句至多有1个else语句,else语句在所有else if语句之后
- if 语句可以有若干个else if语句,它们必须在else语句之前
- 一旦其中一个else if语句检测为true,其他else if以及else语句都将跳过执行。
示例
package struct;import java.util.Scanner;public class IfDemo03 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入成绩:"); int score = scanner.nextInt(); if (score==100){ System.out.println("恭喜满分!"); }else if (score<100 && score>=90){ System.out.println("优"); }else if (score<90 && score>=80){ System.out.println("良"); }else if (score<80 && score>=60){ System.out.println("及格"); }else if (score<60 && score>=0){ System.out.println("不及格"); }else { System.out.println("成绩不合法"); } scanner.close(); }}
if 嵌套结构
语法:
if(布尔表达式1){ if(布尔表达式2){ }}
switch多选择结构
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为分支。
switch语句中的变量类型可以是:
- byte、short、int或者char
- 从Java SE 7开始
- switch支持字符串String类型了
- 同时case标签必须为字符串常量或字面量
语法:
switch(表达式){ case value: //语句 break;//可选 case value: //语句 break;//可选 //你可以有任意数量的case语句 default://可选 //语句}
示例
package struct;public class SwitchDemo02 { public static void main(String[] args) { String name = "拼音"; switch (name){ case "拼音": System.out.println("拼音"); break; case "汉字": System.out.println("汉字"); break; default: System.out.println("弄啥呢"); } }}
- 字符串本质还是数字(hashcode)
- 反编译 java—class(字节码文件)—反编译(IDEA)
循环结构
- while循环
- do……while循环
- for循环
在Java5中引入了一种主要用于数组的增强型for循环
while循环
while是最基本的循环,结构为
while(布尔表达式){
//循环内容
}
只要布尔表达式为true,循环就会一直执行下去
我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环
少部分情况需要循环一直执行,比如服务器的请求响应监听等
循环条件一直为true就会造成无线循环(死循环),我们正常的业务编程中应该尽量避免死循环,会影响程序性能或者造成程序卡死崩溃!
示例1:
package struct;
public class WhileDemo01 {
public static void main(String[] args) {
// 输出1~100
int i = 0;
while (i<100){
i = i +1;
System.out.println(i);
}
}
}
示例2
package struct;
public class WhileDemo02 {
public static void main(String[] args) {
// 死循环
while (true){
//等待客户连接
//定时检测
// ....
}
}
}
示例3
package struct;
public class WhileDemo03 {
public static void main(String[] args) {
// 计算1+2+3+……+100=?
//
int i = 0;
int sum = 0;
while (i<=100){
sum = sum +i;
i = i +1;
}
System.out.println(sum);
}
}
do…while循环
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次
do…while循环和while循环相似,不同的是do…while循环至少执行一次。
do{ // 代码语句}while(布尔表达式);
while和do…while区别:
- while先判断后执行,do…while先执行后判断
- do…while总是保证循环体会被至少执行一次,这是他们的主要差别。
示例1:
package struct;public class DoWhileDemo01 { public static void main(String[] args) { int i = 0; int sum = 0; do { sum = sum + i; i = i +1; }while (i <=100); System.out.println(sum); }}
示例2:
package struct;public class DoWhileDemo02 { public static void main(String[] args) { int a = 0; while (a<0){ System.out.println(a); a = a +1; } System.out.println("==================="); do { System.out.println(a); a = a + 1; }while(a<0); }}
for循环
虽然所有循环结构都可以用while或者do…while表示,但Java提供另一种语句——for循环,使一些循环结构变得更加简单。
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
for循环执行的次数是在执行前就确定的。语法格式如下:
for(初始化;布尔表达式;更新){ //代码语句}
package struct;public class ForDome01 { public static void main(String[] args) { int a = 1; //初始化条件 while (a<=100){ //条件判断 System.out.println(a);//循环体 a +=2; //迭代 } System.out.println("while循环结束!"); //初始化//条件判断//迭代 for (int i=1;i<=100;i++){ System.out.println(i); } System.out.println("for循环结束!"); // 1 // 2 // 3 for (int i = 0; i < 100; i++) { } }}
关于for循环有以下几点说明:
- 最先执行初始化步骤,可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句
- 然后,检测布尔表达式值,如果为true循环体被执行,如果为false循环终止开始执行循环体后面的语句
- 执行一次循环后更新循环体控制变量(迭代因子控制循环变量的增减)
- 再次检测布尔表达式,循环执行上面的过程
输出1~100 语句快捷 100.for
- 练习1:计算0到100之间的奇数和偶数的和
package struct;public class ForDemo02 { public static void main(String[] args) { // 练习1:计算0到100之间的奇数和偶数的和 int oddSum = 0; int evenSum = 0; for (int i = 0; i < 100; i++) { if (i%2!=0){ //奇数公式 oddSum+=i; // oddSum = oddSum + i; }else{ // 偶数 evenSum+=i; } } System.out.println("奇数和:"+oddSum); System.out.println("偶数和:"+evenSum); }}
- 练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
package struct;public class ForDemo03 { public static void main(String[] args) { // 练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个 for (int i = 0; i < 1000; i++) { if (i%5==0){ System.out.print(i+"\t"); }if (i%(5*3)==0){ System.out.println(); //System.out.print("\n"); } } // println 输出后会换行 // print 输出后不会换行 需要转义符 }}
- 练习3:打印九九乘法表
package struct;public class ForDemo04 { public static void main(String[] args) { // 练习3:打印九九乘法表 // 1.我们先打印第一列 // 2.我们把固定的1再用循环抱起来 // 3.去掉重复项 i <= j // 4.调整样式 /* for (int j = 1; j <= 9; j++) { for (int i = 1; i <= j; i++) { System.out.print(i + "*" + j + "=" + (j * i) + "\t"); } System.out.println(); } */ for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j + "*" + i + "=" + (j * i) + "\t"); } System.out.println(); } }}
增强for循环
这里我们先只是见一面,做个了解,之后数组我们重点使用
java5引入了一种主要用于数组或集合的增强型for循环
Java增强for循环语法格式如下:
for(声明语句:表达式){ //代码句子}
- 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定再循环语句块,其值与此时数组元素的值相等。
- 表达式:表达式要访问的数组名,或者是返回值为数组的方法。
package struct;public class ForDemo05 { public static void main(String[] args) { int[] numbers ={10,20,30,40,50}; //定义了一个数组 for (int i=0;i<5;i++){ System.out.println(numbers[i]); } System.out.println("================="); // 遍历数组的元素 for (int x:numbers){ System.out.println(x); } }}
break、continue
break用于强行退出循环,不执行循环中剩余语句
package struct;public class BreakDemo { public static void main(String[] args) { int i = 0; while (i<100){ i++; System.out.println(i); if (i==30){ break; } } }}
continue用于终止某次循环过程,即跳出循环体中尚未执行的语句,接着进行下一次是否执行循环判定
package struct;public class ContinueDemo { public static void main(String[] args) { int i = 0; while (i<100){ i++; if (i%10==0){ System.out.println(); continue; } System.out.print(i); } }}
拓展示例:
package struct;public class LableDemo { public static void main(String[] args) { // 打印101~150之间所有的质数 int count = 0; // 不建议使用此方法 outer:for (int i = 101;i<150;i++){ for (int j = 2;j<i/2;j++){ if (i%j==0){ continue outer; } } System.out.print(i+" "); } }}
拓展三角形
package struct;
public class TestDemo01 {
public static void main(String[] args) {
// 打印三角形 5行
for (int i = 1; i <= 5; i++) {
for (int j = 5; j >= i; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
for (int j = 1;j<i;j++){
System.out.print("*");
}
System.out.println();
}
}
}
Java方法
方法
System.out.println() System 是类 out是对象 println() 是方法
方法是语句的集合,它们在一起执行一个功能
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
注意方法的命名规则 首字母小写 驼峰命名方式
示例:
package method;public class Demo01 { // main 方法 public static void main(String[] args) {// int sum = add(1,2);// System.out.println(sum); test(); } // 加法 public static int add(int a,int b){ return a+b; } public static void test(){ for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j + "*" + i + "=" + (j * i) + "\t"); } System.out.println(); } }}
方法的定义
- Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
- 方法包含一个方法头和一个方法体 下面是一个方法的所有部分:
- 修饰符:这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:在方法被调用时勇于接受外界输入的数据。
- 实参:调用方法时实际传给方法的数据。
- 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){ …… 方法体 …… return 返回值;}
方法调用
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值来选择。
当方法返回一个值的时候,方法调用通常被当作一个值。例如:
int larger=max(30,40)
如果返回值是void,方法调用一定是一条语句。
System.out.println("Hello World!");
了解值传递(Java)和引用传递
示例:
package method;
public class Demo02 {
public static void main(String[] args) {
int max=max(20,20);
System.out.println(max);
}
// 比大小
public static int max(int num1,int num2){
int result = 0;
if (num1==num2){
System.out.println("num1==num2");
return 0; // 终止方法
}else if (num1>num2){
result=num1;
}else{
result=num2;
}
return result;
}
}
方法的重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法的重载的规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为方法的重载
实现理论:
- 方法名称相同时,编译器会根据调用的方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
示例:
package method;public class Demo02 { public static void main(String[] args) { int max=max(10,20); System.out.println(max); } // 比大小 public static double max(double num1,double num2){ //参数名相同”max“,参数类型不同 double result = 0; if (num1==num2){ System.out.println("num1==num2"); return 0; // 终止方法 }else if (num1>num2){ result=num1; }else{ result=num2; } return result; } // 比大小 public static int max(int num1,int num2){ //参数名相同"max",参数类型不同 int result = 0; if (num1==num2){ System.out.println("num1==num2"); return 0; // 终止方法 }else if (num1>num2){ result=num1; }else{ result=num2; } return result; }}
命令行传参
有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
public class CommandLine{ public static void main(String args[]){ for(int i = 0; i<args.length;i++){ System.out.pringln("args["+i+"]:" + args[i]); } }}
命令行传参需要在”CMD“下执行
\src\method>javac Demo03.java\src>java method.Demo03 This is Java Studyargs[0]:Thisargs[1]:isargs[2]:Javaargs[3]:Study
可变参数
JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
在方法声明中,在指定参数类型后加一个省略号(…)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明
publiec static void printMax(double... numbers){ if(numbers.length == 0){ System.out.println("No argument passed"); return; } double result = numbers[0]; // 排序 for(int i = 1;i<numbers.length;i++){ if(number[i]>result){ result = numbers[i]; } } System.out.println("The max value is " +result);}
递归
A方法调用B方法,我们很容易理解
递归就是A方法调用A方法就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于拥有限的语句来定义对象的无限集合。
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法
package method;
public class Demo05 {
public static void main(String[] args) {
System.out.println(f(5));
}
// 5! 5*4*3*2*1
public static int f(int n){
if (n==1){
return 1;
}else{
return n*f(n-1);
}
}
}
数组
数组的定义
数组事相同类型数据的有序集合
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
其中,每一个数据称作数组元素,每个数组元素可以通过一个下标来访问它们。
数组声明创建
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar; //首选的方法或dataType arrayRefVar[]; //效果相同,但不是首选方法
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
数组的元素是通过索引访问的,数组索引从0开始。
获取数组长度:
arrays.length
示例:
package array;public class ArrayDemo01 { // 变量类型 变量名称 = 变量值; // 数组类型 public static void main(String[] args) { int[] nums; // 1.声明(定义) Java推荐使用方式 // int nums2[]; // 早期方式 nums = new int[10]; // 2.创建 这里可以存放10个int数字 // 3.给数组元素中赋值 nums[0] = 1; nums[1] = 2; nums[2] = 3; nums[3] = 4; nums[4] = 5; nums[5] = 6; nums[6] = 7; nums[7] = 8; nums[8] = 9; nums[9] = 10; // 计算所以元素和 int sum=0; for (int i=0;i<nums.length;i++){ sum=sum+nums[i]; } System.out.println("总和为:"+sum); }}
内存分析
Java内存分析
- 堆
- 存放new的对象和数组
- 可以被所有的线程共享,不会存放别的对象引用
- 栈
- 存放基本变量类型(会包含这个基本类型的具体数值)
- 引用对象的变量(会存放这个引用在堆里面的具体地址)
- 方法区
- 可以被所有现场共享
- 包含了所有的class和static变量
写代码画图分析内存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LooFRksL-1628503217427)(java基础.assets/image-20210805155905405.png)]
三种初始化
- 静态初始化
int[]a={1,2,3};
Man[] mans={new Man(1,1),new Man(2,2)};
- 动态初始化
int[]a=new int[2];a[0]=1;a[1]=2;
- 数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
package array;
public class ArrayDemo02 {
public static void main(String[] args) {
// 静态初始化 创建+赋值
int[] a = {1,2,3,4,5,6,7,8};
System.out.println(a[0]);
// 动态初始化 包含默认初始化
int[] b = new int[10];
b[0] = 10;
System.out.println(b[1]);
}
}
数组的四个基本特点
- 其长度的确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
数组边界
- 下标的合法区间:[0,length-1],如果越界就会报错:
public static void main(String[] args){
int[] a = new int[2];
System.out.println(a[2]);
}
- 错误信息:ArrayIndexOutOfBoundsException 数组下标越界异常
- 小结
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合
- 数字也是对象。数组元素相当于对象的成员变量
- 数组长度的确定,不可变的。如果越界,则报ArrayIndexOutOfBoundException
数组使用
- 普通for循环
- For-Each循环
- 数组作方法入参
- 数组作返回值
package array;
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//JDK 不再使用下标 方便输出使用
// for (int array : arrays) {
// System.out.println(array);
// }
// printArray(arrays);
int[] reverse = reverse(arrays);
printArray(reverse);
}
// 打印数组元素
// 反转数组
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反转操作
for (int i = 0, j=result.length-1;i < arrays.length; i++,j--) {
// result[] = array[i];
result[j]= arrays[i];
}
return result;
}
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]+" ");
}
}
}
多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
二维数组
int a[][]=new int[2][5];
解析:以上二维数组a可以看成一个两行五列的数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACwayQ4R-1628503217429)(java基础.assets/image-20210809135412186.png)]
package array;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
public class ArrayDemo05 {
public static void main(String[] args) {
//[4]行[2]列
/*
1,2 array[]
2,3 array[]
3,4 array[]
4,5 array[]
*/
int[][] array = {{1,2},{2,3},{3,4},{4,5}};
System.out.println(array[0][0]);
System.out.println(array[0][1]);
printArray(array[0]);
System.out.println("=================");
for (int i = 0; i < array.length;i++){
for (int j = 0; j < array[i].length;j++){
System.out.println(array[i][j]);
}
}
}
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]+" ");
}
}
}
Arrays类
数组的工具类java.util.Arrays
由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
查看JDK帮助文档
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
具体以下常用功能:
- 给数组赋值:通过fill方法
- 对数组排序:通过sort方法,按升序。
- 比较数组:通过equals方法比较数组中元素值是否相等
- 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
package array;
import java.util.Arrays;
public class ArrayDemo06 {
public static void main(String[] args) {
int [] a = {1,233289,84784,3,12,3,412,4};
// 打印数组元素Arrays.toString
System.out.println(Arrays.toString(a));
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}
public static void pringArray(int[] a){
for (int i = 0;i<a.length;i++){
System.out.print(a[i]+",");
}
}
}
冒泡排序
- 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!
- 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层一次比较,江湖中人人尽皆知。
- 我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为0(n2)
package array;
import java.util.Arrays;
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a = {1,8,4,2,3,10,6,5,9,7};
int[] sort = sort(a); // 调用我们自己写的排序方法
System.out.println(Arrays.toString(sort));
}
//冒泡排序
// 1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
// 2.每一次比较,都会产生出一个最大,或者最小的数字;
// 3. 下一轮则,可以少一次排序!
// 4.依次循环,直到结束!
public static int[] sort(int[] array){
// 临时变量
int temp = 0;
//外层循环,判定要走多少次
for (int i = 0; i <array.length-1;i++){
boolean flag = false; //通过flag标识位减少没有意义的比较
// 内存循环,比较判定两个数,如果第一个数比第二个数大,则交换位置
for (int j = 0; j<array.length-1-i;j++){
if (array[j+1] < array[j]){ // < 换为> 则从大到小
temp = array[j];
array[j]=array[j+1];
array[j+1]=temp;
flag = true;
}
}
if (flag==false){
break;
}
}
return array;
}
}
稀疏数组
当一个数组中大部分元素为0,或为同一个数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具体不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
package array;
public class ArrayDemo08 {
public static void main(String[] args) {
// 创建一个二维数组 11*11 0:没有棋子 1:黑棋 2:白棋
int[][] array1=new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
// 输出原始的数组
System.out.println("输出原始的数组");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
System.out.println("======================");
// 转换稀疏数组
// 获取有效值个数
int sum = 0;
for (int i = 0;i < 11;i++){
for (int j = 0; j < 11;j++){
if (array1[i][j]!=0) {
sum++;
}
}
}
System.out.println("有效个数:"+sum);
// 创建一个稀疏数组的数组
int[][] array2=new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
// 遍历二维数组,将非零的值,存放在稀疏数组中
int count = 0;
for (int i = 0;i < array1.length;i++){
for (int j = 0; j < array1[i].length;j++){
if (array1[i][j] != 0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
System.out.println("稀疏数组");
for (int i = 0;i < array2.length;i++){
System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]+"\t");
}
System.out.println("===================");
System.out.println("还原");
// 读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
// 给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]]= array2[i][2];
}
// 打印
System.out.println("输出还原的数组");
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}
面向对象
面向过程&面向对象
- 面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么……
- 面对过程适合处理一些较为简单的问题
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,是和处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
什么是面向对象
- 面向对象编程(Object-Oriented Programming,OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
- 抽象
- 三大特性
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板
回顾方法及加深
-
方法及定义
- 修饰符
- 返回类型
- break:跳出switch,结束循环 和return区别
- 方法名:注意规范 见名知意
- 参数列表 参数类型 参数名
- 异常抛出
package oop.dome01; import java.io.IOError; import java.io.IOException; // class 类 public class Demo01 { // main 方法 public static void main(String[] args) { } /* 修饰符 返回值类型 方法名(...){ // 方法体 return 返回值 (返回值是什么类型对应 修饰符后面的返回值类型) } */ public String sayHello(){ return "hello world!"; } public void hello(){ //void 空值 return; // 直接return;就行 结束方法 返回一个结果 } public int max(int a,int b){ return a > b ? a : b; // 三元运算符 } // 异常抛出 public void readFile(String file) throws IOException{ } }
-
方法调用
- 静态方法
- 非静态方法
package oop.dome01; public class Demo02 { //静态方法 static //非静态方法 public static void main(String[] args) { // 实例化这个类 new // 对象类型 对象名字=对象值 Student student = new Student(); student.say(); } // 和类一起加载的 public static void a(){ b(); } // 类实例化后才存在 public void b(){ } } package oop.dome01; // 学生类 public class Student { // 非静态方法 没有加static public void say(){ System.out.println("学生说话了"); } }
- 形参和实参
package oop.dome01; public class Demo03 { public static void main(String[] args) { // new Demo03().add(1,2); // 方法1 int add = Demo03.add(1,2); // 1 2 实参 System.out.println(add); } // 方法1 /* public int add(int a,int b){ return a+b; } */ // 方法2 public static int add (int a,int b){ // a b 形参 return a+b; } }
- 值传递和引用传递
package oop.dome01; // 值传递 public class Demo04 { public static void main(String[] args) { int a = 1; System.out.println(a); Demo04.change(a); System.out.println(a); } // 返回值为空 public static void change(int a){ //形参 没有返回值 a = 10; } }
package oop.dome01; // 引用传递 public class Demo05 { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name); // null Demo05.change(person); System.out.println(person.name); // singki } public static void change(Person person){ // person 是一个对象 指向Person类 person.name="singk"; } } class Person{ String name; // null }
- this关键字
类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事务整体描述/定义,但并不能代表某一个具体的事务
- 动物、植物、手机、电脑……
- Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体的事务应该具备的特点和行为(属性)
- 对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
- 能够体现出特点,展现出功能的是具体的实例而不是一个抽象的概念。
创建与初始化对象
- 使用new关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
- 构造器必须要掌握
- new 本质是调用构造方法
- 初始化对象方法
- 定义有参构造之后,必须定义一个无参构造
- 构造器快捷键 alt+insert
package oop.dome02;
// 一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
// 类是抽象的,需要实例化
// 类实例化后会返回一个自己的对象
// student对象就是一个Student类的具体实例!
Student student = new Student();
Student xiaoming = new Student();
xiaoming.name = "小明";
xiaoming.age = 10;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
}
}
package oop.dome02;
// 学生类
public class Student {
// 属性:字段
String name; // null
int age; // 0
// 方法
public void study(){
System.out.println(this.name+"在学习");
}
}
// Person -->> 身高、体重、年龄、国籍
// 学程序好?对世界更好的建模!
构造器示例
package oop.dome02;
// java -->class
public class Person {
// 一个类什么都不写,它也是存在一个方法(public Person(){})
String name;
//实例化初始值
// 1.使用new关键字,必须要有构造器 本质是在调用构造器
public Person(){
//this.name = "doubletoc"; // 存在有参构造,无参只显示定义,不需要其他内容
}
// 有参构造 一旦定义了有参构造,无参就必须显示定义
public Person(String name){
this.name=name;
}
}
/*
public static void main(String[] args) {
// new 实例化了一个对象
Person person = new Person("doubletoc");
System.out.println(person.name);
}
*/
封装
- 该露的露,该藏的藏
- 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合是仅暴露少量的方法给外部使用。
- 封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 记住这句话就够了 ---- 属性私有,get/set
封装意义
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口,规范操作
- 提高系统可维护性
package oop.Demo04;
// 类 private:私有
public class Student {
// 名字
private String name;
// 学号
private int id;
// 性别
private char sex;
private int age;
//学习()
//生活
// 提供一些可以操作这个属性的方法
// 提供一些public的get、set方法
// get 获得这个数据
public String getName(){
return this.name;
}
// set 给这个数据设置值
public void setName(String name){
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120 || age <0){
this.age=3;
}else {
this.age = age;
}
}
}
/*
package oop;
import oop.Demo03.Pet;
import oop.Demo04.Student;
// 一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("doubletoc");
System.out.println(s1.getName());
s1.setAge(73);
System.out.println(s1.getAge());
}
}
*/