Java基础篇-笔记 p1-p75

 2023-09-25 阅读 80 评论 0

摘要:Java 从这里启航 文章目录Java 从这里启航@[TOC]常见的 DOS 命令首先进入运行窗口 (快捷键 win + R)查看目录下的内容文件夹操作Java 语言特点Java 的术语JDK 测试安装成功JDK 环境变量配置成功Java的第一个程序Java 的执行机制书写格式可视化Java代码编

Java 从这里启航

文章目录

常见的 DOS 命令

首先进入运行窗口 (快捷键 win + R)

在这里插入图片描述

查看目录下的内容

在这里插入图片描述

dir: 查看目录下容

文件夹操作

在这里插入图片描述

cd: 进入一个文件夹
md: 创建一个文件夹
cd…: 返回上级文件夹

在这里插入图片描述

echo > : 写入文件
type: 查询文件内容
echo >>: 文本追加
del: 文本删除
rd: 文件夹删除

在这里插入图片描述

cls: 清空屏幕

程序是为了模拟现实世界,解决现实问题而使用计算机语言编写的一系列有序的指令集合。

Java 语言特点


面向对象: 重点放在数据(对象)和对象的接口上进行的一种程序设计技术
简单性: Java 剔除了 C++当中许多很少使用,难以理解,容易混淆的特性
跨平台: 一次编译,到处运行,跨操作系统、服务器运行
开源: 免费,可以对源代码进行修改

Java 的术语


JVM (Java Virtual Machine) Java 的虚拟机:

使用软件在不同操作系统中,模拟相同的环境

JRE (Java Runtime Environment) Java 的运行环境:

JVM + 解释器

JDK (Java Development Kit) Java 的开发工具:

JRE + 类库 + 开发工具包(编译器+调试工具)


JDK 测试安装成功


JDK 环境变量配置成功


Java的第一个程序
class HelloWorld{public static void main(String[] args){System.out.println("Hello World");}
}
Hello World

请添加图片描述

Java 的执行机制

先将源文件(.java)编译成字节码文件(.class), 再将字节码文件进行解释执行
Java的设计模式: “Run Once Run Anywhere“

书写格式
public class HelloWorld{ 
// public: Java语言访问权限关键字
// class: Java语言声明一个类的关键字
// HelloWorld: 表示Java语言的一个文件名,这个名称必须与文件名相同
// 当前这个类的作用范围public static void main(String[] args){// {}:当前代码的作用范围// static: Java语言的关键字,表示静态的// void: Java语言的关键字,表示无返回任何数据类型的值// main: 方法名称,表示Java程序的入口System.out.println("Hello");System.out.println("World");}
}

可视化Java代码编辑器-Eclipse

创建一个.java文件并运行

请添加图片描述请添加图片描述请添加图片描述
请添加图片描述


Java 的关键字


被Java赋予了特定含义的单词

请添加图片描述


Java 的标识符


标识符的命名规则
1. 组成规则
英文大小写字母[a-z][A-Z]、数字字符[0-9]、特殊符号 $ _
2. 注意事项
不能以数字开头、不能使用java关键字、区分大小写

标识符的规范
包名 package name
包名全部小写,一般是公司的域名倒着写 例: com.jf.java
类名 class name
首字母大写,多个单词连接的类名,使用驼峰法书写 例: Demo TestDemo

public class Test2 {
// 命名的名称需要见名知意public static final int MAX_NUMBER = 100; //常量名需全部大写public static void main(String[] args) {int numOne = 1; //驼峰式写法int numTwo = 2;System.out.print(numOne+numTwo);}public int getNum() { //方法名写法return 0;}
}

Java的编程基础

Java 的基本数据类型
public class HelloWorld {int a = 20; //成员变量public static void main(String[] args) {int num = 10; //局部变量/** 八种基本数据类型* 数据类型*/byte by = 10; 		//占用1个字符,取值范围-128~127short sh = 20;		//占用2个字符,取值范围-32768~32767int in = 30;		//占用4个字符long lon = 40;		//占用8个字符float fl = 1.1F;	//占用4个字符double dou = 1.5D;	//占用8个字符char ch = 'a';		//占用2个字符,取值范围0~65536boolean boo = true; //占用字节不确定/** 定义变量的格式* 数据类型 变量名; 声明一个变量* 变量名 = 值;	   赋值一个变量* * 上述都是声明 + 赋值*/int a;a = 20; // 分步操作/** ASCII码的输出*/char c = 97;System.out.println(c); //输出: a}
}
基本数据类型转换
public class Test1 {public static void main(String[] args) {// 容量小的数据类型向容量大的直接转换// 反之,需要进行强制转换,但注意会出现精度的丢失或数据的溢出byte b1 = 1;short b2 = b1; // 自然转换short b3 = 1;byte b4 = (byte) b3; // 强制转换char ch = '陈';int result = ch; // 转换成字节形式输出System.out.println(result); // 38472/** 下面的三个转换是由整数转换成浮点数* 可能会存在丢失精度* * 如果用于表示货币值,不建议使用float或double*/int num1 = 30;float fl1 = num1;System.out.println(fl1); //近似值int num2 = 30;double dou1 = num2;System.out.println(dou1); //近似值long num3 = 30;double dou2 = num3;System.out.println(dou2); //近似值// 面试题:short s1 = 10;s1 = (short) (s1 + 1); // 需要强制转换,因为short进行运算的时候会转换成int类型// byte、short、int都存在这个问题System.out.println(s1);} 
}
转义字符的演示
public class Test2 {public static void main(String[] args) {// 转义字符:用于转换符号的字符System.out.println("转行");System.out.print("转义字符,我是一个回车符\n");System.out.println("\t我是一个制表符"); //我是可以自适应的System.out.println("\\我是一个斜杠,前面那位是转义我的");System.out.println("\"我是一个双引号,前面那位是转义我的");System.out.println("\'我是一个单引号,前面那位是转义我的");}
}
转行
转义字符,我是一个换行符我是一个制表符
\我是一个斜杠,前面那位是转义我的
"我是一个引号,前面那位是转义我的'
运算符
import java.util.Scanner;public class Test3 {public static void main(String[] args) {int a = 5;int b = 2;System.out.printf("加法运算: a + b = %d ",a+b);System.out.printf("减法运算: a - b = %d ",a-b);System.out.printf("乘法运算: a * b = %d ",a*b);System.out.printf("除法运算: a / b = %d ",a/b);System.out.printf("取模运算: %d ", a%b);System.out.println("----换行----");// 先自增int num1 = a++;System.out.printf("我是先赋值,后自增: %d ",num1); // a = 5System.out.printf("自增后 a 的值: %d ",a); // a = 6// 后自增int num2 = ++b;System.out.printf("我是先自增,后赋值: %d ",num2); // b = 3System.out.printf("自增后 b 的值: %d ",b); // b = 3System.out.println("----换行----");/** 赋值运算符*/
//		 a += 1;
//		 a -= 1;
//		 a *= 2;
//		 a /= 2;
//		 a %= 2;// 面试题:short s = 10;s += 1;System.out.printf("我是 short 类型下使用赋值运算符计算的结果: %d",s); // 我是不用进行强制进行转换System.out.println("----换行----");/** 关系运算符*/System.out.printf("a=%d,b=%d ",a,b);System.out.printf("a==b: %b ",a==b);System.out.printf("a!=b: %b ",a!=b);System.out.printf("a>b: %b ",a>b);System.out.printf("a<b: %b ",a<b);System.out.printf("a>=b: %b ",a>=b);System.out.printf("a<=b: %b ",a<=b);System.out.println("----换行----");// 创建一个键盘输入的工具Scanner input = new Scanner(System.in);System.out.print("请输入一个整数值: ");int num3 = input.nextInt(); // 系统获取刚才输入的整数值System.out.printf("整数值为: %d",num3);input.close();}
}
加法运算: a + b = 7 减法运算: a - b = 3 乘法运算: a * b = 10 除法运算: a / b = 2 取模运算: 1 ----换行----
我是先赋值,后自增: 5 自增后 a 的值: 6 我是先自增,后赋值: 3 自增后 b 的值: 3 ----换行----
我是 short 类型下使用赋值运算符计算的结果: 11----换行----
a=6,b=3 a==b: false a!=b: true a>b: true a<b: false a>=b: true a<=b: false ----换行----
请输入一个整数值: 4
整数值为: 4
逻辑运算符
public class Test4 {public static void main(String[] args) {/** 逻辑运算符*/boolean a = true;boolean b = false;// 与运算:分别计算表达式两边的结果再作与运算,两边同时为true的时候,结果为trueSystem.out.printf("a&b is %b\n", a&b);// 或运算:分别计算表达式两边的结果再作与运算,两边只要有一个为true,结果为trueSystem.out.printf("a|b is %b\n", a|b);// 异或运算:分别计算表达式两边的结果再作与运算,两边结果相异为true,相同为falseSystem.out.printf("a^b is %b\n", a^b);// 非运算:System.out.printf("!a is %b\n", !a);// 短路与:System.out.printf("a&&b is %b\n", a&&b);// 短路或:System.out.printf("a||b is %b\n", a||b);/* 面试题:* & vs &&:* &:在逻辑运算时分别计算表达式两边的结果,再作&运算,在做位运算时&表示按位与* &&短路与运算,先计算左边的表达式,如果结果是false,那么不用计算右边表达式,直接返回false,* 如果左边的表达式结果是true,再计算右边的表达式,如果右边的表达式为true,结果为true,否则为false* | 和 ||的原理同上。* 所以短路与 或 短路或的计算效率更高,建议使用。*/// 面试题:以最快的速度计算8*4结果?System.out.println(8<<2);}
}
a&b is false
a|b is true
a^b is true
!a is false
a&&b is false
a||b is true
8*4 结果是 32
位运算
public class Test5 {public static void main(String[] args) {/** 位运算*/// 左移运算:位移数作为2次幂与操作数相乘System.out.println(8<<2);// 右移运算:操作数除以位移数的2次幂System.out.println(8>>2);// 通过键盘输入,初始化两个数将这两个数据交换位置后,输出显示交换后的数据。Scanner input = new Scanner(System.in);System.out.println("请输入第一个数"); // 32int a = input.nextInt();System.out.println("请输入第二个数"); // 2int b = input.nextInt();// (1)通过第三个变量来交换int c = a;a = b;b = c;System.out.println("a="+a+",b="+b);// (2)不通过第三个变量如何交换两个数?// 1.通过表达式a = a+b-(b=a);// 2.通过+-计算a=a+b;b=a-b;a=a-b;// 3.通过异或,两个数交换位置最快的方法a = a^b;b = a^b;a = a^b;	input.close();}
}
三目运算符
/** 三目运算符*/
import java.util.Scanner;public class Test6 {public static void main(String[] args) {System.out.println("请输入一个成绩: ");Scanner input = new Scanner(System.in);int score = input.nextInt();// boolean result = score>=60?true:false;// String表示一个字符串类型,不是一个基本数据类型String result = score >= 60? "及格":"不及格";System.out.println(result);input.close();}}
if 条件判断语句
public class Test7 {public static void main(String[] args) {// 1、输入一个数字,这个数字转码可以为一个字母,判断是大写字母还是小写字母,输出提示信息。Scanner input = new Scanner(System.in);System.out.println("请输入一个数字,范围是65-122:"); // 65是A,97是a,122是zint c = input.nextInt();if(c>=65 && c<=90){System.out.println("您输入的是一个大写字母"+(char)c);}else {System.out.println("您输入的是一个小写字母"+(char)c);}// 2、写一个程序,判断某一年是否为闰年是闰年否则是平年// 被 4 整除但不能被 100 整除能被 400 整除System.out.println("请输入年份:");int year = input.nextInt();if((year%4==0 && year%100!=0) || year%400==0){System.out.println("是闰年");}else{System.out.println("平年");}// 3、给出一个百分制成绩,要求输出成绩等级‘A’、‘B’、‘C’、‘D’、‘E’。// 90分以上输出’A’,80~89分输出’B’,70~79分输出’C’,// 60~69分输出’D’,60分以下输出‘E’System.out.println("输入一个成绩:");int score = input.nextInt();if(score>=90){System.out.println("A");}else if(score<90 && score >=80){System.out.println("B");}else if(score<80 && score >=70){System.out.println("C");}else if(score<70 && score >=60){System.out.println("D");}else if(score<60){System.out.println("E");}input.close();}
}
switch 分支语句
public class Test8 {public static void main(String[] args) {Scanner input = new Scanner(System.in);System.out.println("今天是星期几?");int day = input.nextInt();/** switch括号内的表达式的返回值必须是int/char/short/byte,1.7后支持String* 每一个case子句必须是唯一的常量值,需要添加break,否则将继续往下执行。* default语句可以省略*/switch(day){case 1:System.out.println("星期一");System.out.println("周一比较堵,请慎重选择出行方式(1公车,2地铁)");int method = input.nextInt();if(method==1){System.out.println("公交出行");}else{System.out.println("地铁出行");}break;case 2:System.out.println("星期二");break;case 3:System.out.println("星期三");break;case 4:System.out.println("星期四");break;case 5:System.out.println("星期五");break;case 6:System.out.println("星期六");break;case 7:System.out.println("星期日");break;default:System.out.println("地球上不适合你,请回火星吧");break;}input.close();}
}
switch分支语句小练习
/** switch分支语句小练习*/
import java.util.Scanner;public class Test9 {// switch分支语句// 直接用JDK1.7的字符串条件判断,确定两个数是执行加、减、乘、除操作。public static void main(String[] args) {Scanner input = new Scanner(System.in);System.out.println("请输入第一个数"); int num1 = input.nextInt();System.out.println("请输入第二个数");int num2 = input.nextInt();System.out.println("请输入操作符(+,-,*,/)");String option = input.next(); // 输入的是字符串switch(option){case "+":int i = 10;System.out.println("num1+num2="+(num1+num2));System.out.println("i="+i);break;case "-":i = 20;System.out.println("num1-num2="+(num1-num2));System.out.println("i="+i);break;case "*":System.out.println("num1*num2="+(num1*num2));break;case "/":System.out.println("num1/num2="+(num1/num2));break;default:System.out.println("输入的操作符有误");break;}input.close();}
}
  1. 在实现分支判断时,匹配成功率高的判断放在前面,可以提高效率
  2. 在表达式中判断,我们尽量使用确定的值去跟不确定的值进行判断
while 循环语句的小练习
//1、计算1-100之间所有整数之和
public class Test10{public static void main(String[] args){int num = 0; 	//计算总数int i = 1; 		//增量while(i<=100){num+=i;i++;}System.out.println(num);// 2、计算 10 的阶乘int i2 = 1;int num2 = 1;while(i2<=10){num *= i;i2++;}System.out.printf("10 的阶乘的结果为: %d\n", num2);// 3、输出1~3中奇数,偶数和3的倍数int i3=1;//增量while(i3<=3){if(i3%2==0){System.out.println("偶数:"+i3);}else{System.out.println("奇数:"+i3);}if(i3%3==0){System.out.println("3的倍数:"+i3);}i3++;}
}
1-100之间所有整数之和为: 5050
10 的阶乘的结果为: 1
奇数:1
偶数:2
奇数:3
3的倍数:3

while循环:先判断,再执行,有可能执行0次

do…while 循环语句的小练习
public class Test11 {public static void main(String[] args){System.out.println("逆序输出3~0的结果:");// 1、逆序输出3~0int i = 3;do{//循环体System.out.println(i);i--;}while(i>=0);//循环条件System.out.println("阶乘求和 1!+2!+...+10!的结果:");// 2、Java阶乘求和 1!+2!+...+10!int num = 0;//记录总和int i2 = 1;do{int j = 1;int jc = 1;//求阶乘的和while(j<=i){jc *=j;j++;}num+=jc;i2++;}while(i2<=10);System.out.println(num);}
}
逆序输出3~0的结果:
3
2
1
0
阶乘求和 1!+2!+...+10!的结果:
10

do while循环:先执行,再判断,最少执行一次

for 循环的六种写法
public class Test12{public static void main(String[] args){System.out.println("标准写法");//1、标准写法 for(int i=0;i<=3;i++){if(i==2){continue;			//跳过当次循环,进入下次循环}System.out.println(i);}System.out.println("表达式1省略,外部声明起点");//(2)表达式1省略,但在外部声明int j = 0;for(;j<3;j++){System.out.println(j);}//(3)死循环: 表达式2省略,死循环 // i的值没有重点//for(int i=0;;i++){//	System.out.println(i);//}System.out.println("表达式3省略,自增声明在循环内部");//(4)表达式3省略,但是要声明在循环内部 for(int i=0;i<3;){System.out.println(i);i++;}System.out.println("表达式3省略,外部声明起点,自增声明在循环内部");//(5)表达式1,3省略,但是要声明在循环的外部和内部int x = 0;for(;x<3;){System.out.println(x);x++;}//(6)死循环:三个表达式都省略,死循环//for(;;){//}}
}
斐波那契数列的查询
public class Test13 {// 输出10个斐波那契(Fibonacci)数列:1 1 2 3 5 8 13 21 34 55。//(特点:第1,2两个数值为1,从第三个数开始,该数是其前面两个数之和)public static void main(String[] args){int n1 = 1;int n2 = 1;int next = 0;System.out.print(n1+" "+n2+" ");for(int i=0;i<8;i++){next = n1 + n2;System.out.print(next+" ");n1 = n2;n2 = next;}System.out.print("\n请输入一个下标查询斐波那契数列中的对应下标的一个数字:");Scanner input = new Scanner(System.in);int num = input.nextInt();int num1 = 1;int num2 = 1;int nextNum = 0;if (num==1||num==2) {System.out.println(1);}else {for(int i=3;i<=num;i++) {nextNum = num1 + num2;num1 = num2;num2 = nextNum;}System.out.printf("查询的下标为%d,查询结果为%d",num,nextNum);}input.close();}
}
1 1 2 3 5 8 13 21 34 55 
请输入一个下标进行查询斐波那契数列中的一个数字:10
查询的下标为10,查询结果为55
for 循环两个有点儿意思的小练习
public class Test14 {public static void main(String[] args){//1、打印九九乘法表//外循环控制行数for(int i=1;i<=9;i++){//内循环控制列数for(int j=1;j<=i;j++){System.out.print(j+"x"+i+"="+(j*i)+"\t");}System.out.println();}//2、打印等腰三角形//外循环控制行数for(int i=1;i<=5;i++){//内循环输出空格for(int j=i;j<5;j++){System.out.print(" ");}//内循环输出*for(int j=1;j<=i*2-1;j++){System.out.print("*");}System.out.println();}}
}
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81	****************
*********

数组与方法

方法(函数)+方法调用+多次调用
import java.util.Scanner;public class Test1 {public static void main(String[] args) {// 1. 方法(函数)+方法调用+多次调用getMenu();// 2. 方法的形参和实参Scanner input = new Scanner(System.in);System.out.println("请输入要打印星星的行数:");int num = input.nextInt();// 在调用方法时传入的参数 num. 称为实参printStar(num); // 静态方法input.close();// 3. 判断是否是闰年int year = 2022; // 传入一个年份boolean bool = isRunNian(year); // 返回是布尔值if(bool){System.out.printf("%d年是闰年\n",year);}else{System.out.printf("%d年是平年\n",year);}// 4. 打印一条文本信息print();}public static void getMenu() {System.out.println("-----菜单-----");System.out.println("1、宫保鸡丁 22");System.out.println("2、韭菜鸡蛋 20");System.out.println("3、红烧狮子头 26");System.out.println("4、滋补牛尾汤 38");System.out.println("5、美颜酱猪蹄 38");};/* 带参数的方法,形参:在方法定义时的参数称为形参*/private static void printStar(int line) { // line = numfor(int i=1;i<=line;i++){ // line = numfor(int j=1;j<=i;j++){System.out.print("*");}System.out.println();}}private static boolean isRunNian(int year) {if((year%4==0 && year%100!=0) || year%400==0) {return true;} else {return false;}}public static void print() {System.out.println("结束了所有工作");}
}
-----菜单-----
1、宫保鸡丁 22
2、韭菜鸡蛋 20
3、红烧狮子头 26
4、滋补牛尾汤 38
5、美颜酱猪蹄 38
请输入要打印星星的行数:
5
*
**
***
****
*****
2022年是平年
结束了所有工作
方法的重载
public class Test2 {public static void main(String[] args) {// 方法的重载:在同一个类中,方法名相同,参数列表不同,返回值不能作为重载的条件。int result1 = add(10,20);       // 整数类型相加System.out.println(result1);float result2 = add(10.1,20.1); // 浮点数相加System.out.println(result2);float result3 = add(10,20.1);   // 整数 + 浮点数System.out.println(result3);}public static int add(int a,int b){return a+b;}public static float add(double a,double b){return (float) (a+b);}public static float add(int a,float b){return a+b;}
}
30
30.2
30.1
数组的定义+数组的遍历+随机数
import java.util.Random;public class Test3 {public static void main(String[] args){/** 数组的定义:一组能够存储相同数据类型的数据集合* 元素:数组中的每个数据称为元素* 开始位置:数组元素的位置从0开始* 下标:数据数组中的位置*/// 1. 四种数组定义方式// 第一种,int[] nums = new int[5];// 插入一个一个的元素/*nums[0] = 1;nums[1] = 2;nums[2] = 3;nums[3] = 4;nums[4] = 5;*/for(int i=0;i<nums.length;i++){nums[i] = i+1;}// 第二种int[] nums2; 		// 先声明(定义)nums2 = new int[5]; // 后赋值// 第三种:int[] nums3 = new int[]{1,2,3,4,5}; // 声明+赋值+内容// 第四种:int[] nums4 = {1,2,3,4,5};//所有的数组都有一个属性是:lengthSystem.out.println("数组 num4 的长度是:"+nums4.length);/** 2. 数组的遍历*/System.out.print("数组的遍历结果:");int[] scores = {59,75,83,93,100};int len = scores.length; // 数组的长度for(int i=0;i<len;i++){int score = scores[i];System.out.print(score + " ");}System.out.println("\n直接打印数组而不是遍历的情况输出是:"+scores); // 数组存入内存的地址System.out.print("JDK1.5之后新特性打印结果:");// forearch JDK1.5之后新增的特性for(int x:scores){System.out.print(x + " ");}System.out.print("\n方法里数组的遍历:");print(scores); // 方法调用一个数组/** 3. 随机数*/Random r = new Random();int ran = r.nextInt(10); // 10 是随机数的取值范围System.out.println("\n生成伪随机数的地址"+r);System.out.println("生成伪随机数是:"+ran);}public static void print(int[] x) {for(int num:x) {System.out.print(num + " ");}}
}
打印正三角形
public class Execise1 {public static void main(String[] args) {// 数组示例:打印正三角形char[] cs = {'A','B','C','D','E','F','G'};int len = cs.length;for(int i=1;i<=len;i++){for(int j=i;j<len;j++){System.out.print(" ");}for(int j=1;j<=i*2-1;j++){System.out.print(cs[i-1]);}System.out.println();}}
}
二维数组的使用+例子
public class Test4 {public static void main(String[] args) {/** 二维数组示例:Java中没有真正的多维数组,多维数组的表示方式还是数组。* 实例:计算几个班的平均分*/int[][] scores = {{78,98,88},{87,96,85},{67,78,89}};int classLen = scores.length; // 计算出还有多少个班级for (int i=0;i<classLen;i++) {int sum = 0; int count = scores[i].length; // 每一个班级下还有几个成绩for (int j=0;j<count;j++) {sum += scores[i][j];}int avg = sum / count; // 每一个班级的平均分System.out.print("第"+(i+1)+"班的平均成绩是:"+avg+"\n");}// 学生成绩名单for (int i=0;i<classLen;i++) {System.out.print("第"+(i+1)+"班的成绩汇总:");for (int j=0;j<scores[i].length;j++) {System.out.print(scores[i][j]+" ");}System.out.println();}}
}
1班的平均成绩是:882班的平均成绩是:893班的平均成绩是:781班的成绩汇总:78 98 882班的成绩汇总:87 96 853班的成绩汇总:67 78 89 
求最大值和最小值
public class Test5 {public static void main(String[] args){// 求数列中的最大值和最小值int[] num = {12,3,54,67,88,34};int max = max(num);System.out.println("数列中的最大值是:"+max);int min = min(num);System.out.println("数列中的最小值是:"+min);}//求数列中的最大值 public static int max(int[] num){int max = num[0];int len = num.length;for(int i=1;i<len;i++){if(num[i]>max){num[i] = num[i]+max;max = num[i]-max; 	 // 最大值数据和被比较的数据进行交换num[i] = num[i]-max; // num[i] = max; max = num[i]}}return max;}//求数列中的最小值 public static int min(int[] num){int min = num[0];int len = num.length;for(int i=1;i<len;i++){if(num[i]<min){num[i] = num[i]+min;min = num[i]-min;num[i] = num[i]-min;}}return min;}
}
冒泡排序算法
/**
冒泡排序算法
*/
public class Test6{public static void main(String[] args){int[] nums = {34,4,56,17,90,65};//待排序的数列//外循环控制轮数for(int i=0;i<nums.length-1;i++){ // 减1是因为第一个数字不需要跟自己比较,总共六个数字需要比较五轮for(int j=0;j<nums.length-1-i;j++){// -i是减少了比较的轮数,每轮送到位的数字不需要再进行比较// 将满足比较条件的成对数据进行交换(后一个大于前一个数字)if(nums[j]>nums[j+1]){nums[j] = nums[j]+nums[j+1];nums[j+1] = nums[j]-nums[j+1];nums[j] = nums[j]-nums[j+1];}}}//输出结果for(int n : nums){System.out.println(n);}	}
}
演示:
/*
34 4 56 17 90 654 34 17 56 65 90	//第一轮 5次
4 17 34 56 65		//第二轮 4次
4 17 34 56			//第三轮 3次
4 17 34				//第四轮 2次
4 17				//第五轮 1次
*/
选择排序算法
/**
选择排序算法
*/
public class Test7{public static void main(String[] args){int[] nums = {34,4,56,17,90,65};//待排序的数列int minIndex = 0; //用于记录每次比较的最小值下标//控制轮数   for(int i=0;i<nums.length-1;i++){minIndex = i;//每轮假设一个最小值下标for(int j=i+1;j<nums.length;j++){// +1将比较的范围往后走一位if(nums[minIndex]>nums[j]){minIndex = j; //把最小值下标找出来是几}}//判断需要交换的数下标是否为自己,不是自己开始交换if(minIndex!=i){nums[minIndex] = nums[minIndex]+nums[i];nums[i] = nums[minIndex]-nums[i];nums[minIndex] = nums[minIndex]-nums[i];}}//输出结果:for(int n: nums){System.out.println(n);}}}// 演示:
/*
34 4 56 17 90 65
4 34 56 17 90 65 第一轮 5次
4 17 56 34 90 65 第二轮 4次
4 17 34 56 90 65 第三轮 3次
4 17 34 56 90 65 第四轮 2次
4 17 34 56 65 90 第五轮 1次
*/
直接插入排序算法
/**
直接插入排序算法
(从后向前找到合适位置后插入)
基本思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的子序列的合适位置(从后向前找到
合适位置后),直到全部插入排序完为止。*/public class Test8{public static void main(String[] args){int[] nums = {34,4,56,17,90,65};//待排序的数列//控制比较的轮数:for(int i=1;i<nums.length;i++){int temp = nums[i];  //记录操作数,用作于最后赋值int j = 0; //遍历是从零开始for(j=i-1;j>=0;j--){if(nums[j]>temp){nums[j+1] = nums[j];}else{break;}}if(nums[j+1]!=temp){ //为了排除和自己交换的可能性,因为如果不满足nums[j]>temp条件时直接break出来了nums[j+1] = temp;}}//输出结果:for(int n : nums){System.out.println(n);}}
}// 演示:
/*
34 4 56 17 90 6534 34 56 17 90 65  j=0    temp[1]=4
4 34 56 17 90 65   j=-1   temp[1]=4  break4 34 56 17 90 65   j=1    temp[2]=56 break 本身4 34 56 56 90 65   j=2    temp[3]=17  
4 34 34 56 90 65   j=1    temp[3]=17
4 17 34 56 90 65   j=0    temp[3]=17 break4 17 34 56 90 65   j=3    temp[4]=90 break 本身4 17 34 56 90 90   j=4    temp[5]=65 
4 17 34 56 65 90   j=3    temp[5]=65 break 
*/
二分法查找
/**二分法查找(折半查找):前提是在已经排好序的数组中,通过将待查找的元素与中间索引值对应的元素进行比较,若大于中间索引值对应的元素,去右半部分查找,否则,去左半部分查找。依此类推。直到找到为止;找不到返回一个负数。
*/
import java.util.Scanner;
public class Test15{public static void main(String[] args){//必须保正数列是有序的int[] num = {10,20,50,65,88,90};int index = binarySearch(num,100);System.out.println(index);}//二分查找算法public static int binarySearch(int[] num,int key){int start = 0;//开始下标int end = num.length-1;//结束下标while(start<=end){int middle = (start+end)/2; //>>>1if(num[middle]>key){end = middle-1;}else if(num[middle]<key){start = middle+1;}else{return middle;}}return -1;}
}
/* 演示找不到的情况:* start=0 end=5 middle=2 num[2]=50 key=100 start=1+2=3 右边* start=3 end=5 middle=4 num[4]=88 key=100 start=4+1=5 右边的右边* start=5 end=5 middle=5 num[5]=90 key=100 start=5+1=6 右边的右边的右边* start=6 end=5 start>end 循环进不去*/
Arrays工具类的使用
/*
Arrays工具类的使用
*/
import java.util.Arrays;public class Test10{public static void main(String[] args){int[] num = {45,65,76,87,98,901};//二分查找int index = Arrays.binarySearch(num,98);System.out.println("找到的下标是: "+index);//输出数组for(int n: num){System.out.println(n);}//在测试输出数据时,可以使用,更加方便System.out.println(Arrays.toString(num));//排序int[] num2 = {10,32,11,44,543,22,12};Arrays.sort(num2);//快速排序System.out.println(Arrays.toString(num2));//①数组的复制,方式一:// num2表示原数组,10表示新数组的长度int[] num3 = Arrays.copyOf(num2,10); System.out.println(Arrays.toString(num3));//②方式二:int[] newNum = new int[num2.length];//num2表示原数组,0表示开始拷贝的位置,newNum表示新数组,0表示新数组拷贝的开始位置,num2.length拷贝后新数组的长度System.arraycopy(num2,0,newNum,0,num2.length);System.out.println(Arrays.toString(newNum));//小结,数组的复制:/*效率由高到低排序是:System.arraycopy -> Arrays.copyOf -> for*///判断两个数组的值是否相等System.out.println(Arrays.equals(num2,newNum));//填充数组 fill(新数组,以0填充空位)Arrays.fill(newNum,0);System.out.println(Arrays.toString(newNum));}
}

面向对象

面向对象内存分析
/**
面向过程:以步骤为单位,一步一步完成某一个具体事情
面向对象:以对象为单位,通过调度组合不同的对象来完成某一个事情*/
public class Test1{public static void main(String[] args){//①创建执行一个对象//声明一个类的变量(除了八种基本数据类型以外,都是引用数据类型,包括数组)Person h = null;  //创建一个Horse类型的对象,实例对象h = new Person();//有了对象,我们就可以调用对象的属性和方法//往类里传数据h.name = "菲力克斯";h.age = 20;//调用类中的方法,那么方法就会被执行。h.run();h.eat();//②匿名对象:只能使用一次,用完后,该对象就会被释放new Person().eat();h =  null;//把对象释放//空指针异常报错:java.lang.NullPointerException//当对象不存在时,调用该对象的属性和方法将报错(空指针)//h.eat();//③对象内存空间的问题:Person h1 = null;Person h2 = null;h1 = new Person();h2 = new Person();h1.name="小白";  //垃圾回收h1.age=4;       //垃圾回收h2.name="小黑";h2.age=5;//h2 = h1这个操作是为了执行指向一个内存空间h2 = h1;//对象之间的赋值,相同类型才可以赋值System.out.println("h1.name输出的结果是: "+h1.name);h2.name="小黑";//赋值了之后,相同内存空间下的名字也会被改变System.out.println("h1.name输出的结果是: "+h1.name);		}
}//自定一个类(类型)
class Person{//在类中定义属性(特征)//字符串是引用类型变量,不是基本数据类型变量String name;int age;public void run(){System.out.println("我是"+name+"今年"+age+"岁"+",我能奔跑");}public void eat(){System.out.println("我特别能吃,能吃三大碗");}
}
我是菲力克斯今年20,我能奔跑
我特别能吃,能吃三大碗
我特别能吃,能吃三大碗 ----> 匿名对象的创建
h1.name输出的结果是: 小白 
h1.name输出的结果是: 小黑
封装性
/*封装性:如果属性没有封装,那么在本类之外创建对象后,可以直接访问属性
*/
public class Test2 {public static void main(String[] args) {People p1 = new People();p1.setName("菲力克斯");p1.setAge(20);p1.toString();p1.run(20); //类中的方法p1 = null;}
}
class People{// private关键字:访问权限修饰符,public表示公有的,private表示私有的,私有的属性或方法,只能在本类中访问,// 公有的属性和方法,可以被类外部的其它类访问,想要在类外部访问私有属性,我们需要提供公有的方法来间接访问,//属性的封装private String name; //成员变量,在类中定义private int age; //成员变量,在类中定义//通常在一个类中,属性都私有化,并对外提供getter and getter方法(访问的方法)//getter and setter//对外提供一个为name属性设值的方法public void setName(String name) {this.name = name;};//对外提供一个获取name属性的方法public String getName() {return name;};public void setAge(int age) {this.age = age;};public int getAge() {return age;};public String toString() {System.out.println("我是"+getName()+"今年"+getAge()+"岁");return "end";};public void run(int len) {int m = len; //成员变量,在类中定义System.out.print("我能跑"+m+"米");};
}
我是菲力克斯今年20岁
我能跑20
构造方法
/**构造方法
*/
public class Test3{public static void main(String[] args){Dog dog1 = new Dog();//对象的初始化工作,new之后就可以直接调用Dog dog2 = new Dog("小狗",5); //创建重载构造方法的一个对象}
}class Dog{//默认构造方法,通常有其它构造方法时,要保留默认构造方法public Dog(){ //方法名称与类名称相同,无返回值类型的声明System.out.println("构造方法执行了");}public Dog(String name){this.name = name;System.out.println("带一个参数的构造方法执行了");}public Dog(String name,int age){this(name);//调用其它构造方法时,此语句需要在第一句,在构造方法相互调用时必须要有出口//this.name = name;this.age = age;System.out.println("带两个参数的构造方法执行了");}private String name;private int age;public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}
}
构造方法执行了
带一个参数的构造方法执行了
带两个参数的构造方法执行了
this关键字
/** this关键字*/
public class Test4{public static void main(String[] args){Cat cat = new Cat();cat.setName("小猫");cat.setAge(3);cat.eat();//调用类中的方法}
}class Cat{private String name;private int age;public void setName(String name){ //name=小猫 setter无返回值this.name = name; //①this代表的是当前对象(cat.name=name)}public String getName(){ // getter返回字符串String return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}public void eat(){//在方法中使用this调用类中的其它②方法或③属性,this可以省略,this前面可以使用当前的类名.thisSystem.out.println("我是"+Cat.this.getName()+",我爱吃鱼"+"---->Cat.this.getName()");//Cat.cat.getName()System.out.println("我是"+this.name+",我爱吃鱼"+"---->this.name");}
}
我是小猫,我爱吃鱼---->Cat.this.getName()
我是小猫,我爱吃鱼---->this.name
值传递
/** 值传递*/
public class Test5{public static void main(String[] args){int x = 10;method(x);System.out.println("x="+x);}public static void method(int mx){mx = 20;}
}
x=10
引用传递
/** 引用传递*/
public class Test6{public static void main(String[] args){Duck d  = new Duck();method(d) ;System.out.println("Duck age = "+d.age);}public static void method(Duck duck){duck.age = 5; //d.age = 5}
}
class Duck{int age = 2;   //省略封装
}
Duck age = 5
方式一:String传递
/** 方式一:String传递* 字符串本身就是一个对象*/
public class Test7{public static void main(String[] args){String name = "小飞";method(name);System.out.println("name="+name) ;}public static void method(String sname){sname = "小备";}
}
name=小飞
方式二:String传递
/** 方式二:String传递*/
public class Test8{public static void main(String[] args){Name n  = new Name();method(n) ;System.out.println("person name = "+n.name) ;}public static void method(Name Nam){Nam.name = "备备"; //n.name = "备备"}
}
class Name{String name = "飞飞";   //省略封装
}
person name = 备备
static 关键字
/**
static 关键字:1、静态变量或方法不属于对象,依赖类2、静态变量是全局变量3、静态变量只有存一份,在静态方法区中存储,静态变量是本类所有对象共享一份4、静态变量是本类所有对象共享一份5、静态方法不能访问非静态属性和方法,只能访问静态。
*/
public class Test10{public static void main(String[] args){//生命周期从类被加载后一直到程序结束System.out.println("args.length:"+args.length);for(String s: args){System.out.println(s);}//Role beibei = new Role("刘备","蜀国");//正常将数据传入类对象中Role bei = new Role("刘备");Role guan = new Role("关羽");System.out.println(bei.getInfo());System.out.println(guan.getInfo());System.out.println("获取到角色的国家"+Role.country);//bei.country = "秦国"; //用创造的对象去修改国家的字段Role.country = "秦国";System.out.println("------------------");System.out.println("修改国家的信息后:"+Role.country);System.out.println("关羽的国家被改后:"+guan.country);//同时全部修改System.out.println("------------------");System.out.println("用类名调用静态变量:"+Role.country);//用类名调用静态变量}
}
//角色类
class Role{private String name;//private String country;static String country = "蜀国";//静态变量(全局变量)常量只需要存储一份,以后传入一个英雄自然对上是蜀国public Role(String name,String country){this.name = name;}public Role(String name){this.name = name;}public void setName(String name){this.name = name;}public String getName(){return name;}//静态方法不能访问非静态的数据/*public static void setCountry(String country){Role.country = country;}public void setCountry(String country){this.country = country; // this == bei}public String getCountry(){return country;}*/public String getInfo(){return "name="+name+",country="+country;}
}
args.length:0
name=刘备,country=蜀国
name=关羽,country=蜀国
获取到角色的国家蜀国
------------------
修改国家的信息后:秦国
关羽的国家被改后:秦国
------------------
用类名调用静态变量:秦国
代码块
public class Test11 {public static void main(String[] args) {Student s = new Student();// 顺序问题:// 静态>普通代码块>构造方法,写法顺序不影响执行顺序s.study();Student s1 = new Student(); //静态代码块只执行一次s1.study();s = null;}
}class Student {public Student() {System.out.println("我是一个构造方法");};{System.out.println("我是一个普通代码块");}static {System.out.println("我是一个静态代码块");}public void study() {//限制作用域{System.out.println("我是类中方法中的代码块");}}
}
我是一个静态代码块
我是一个普通代码块
我是一个构造方法
我是类中方法中的代码块
我是一个普通代码块
我是一个构造方法
我是类中方法中的代码块
单例设计模式
/**
单例设计模式:在项目中为什么要使用单例,单例有什么好处?1、在设计一些工具类的时候(通常工具类,只有功能方法,没有属性)2、工具类可能会被频繁调用目的是为了节省重复创建对象所带来的内存消耗,从而来提高效率使用构造方法私有化+静态方法来替代单例
*/
public class Test12 {public static void main(String[] args) {Singleton1 s = Singleton1.getInstance();s.print();Singleton2.getInstance();//静态方法可以直接调用Singleton2 s2 = Singleton2.getInstance();s2.print();//print()方法不是一个静态方法Tools.print1();Tools.print2();}
}
//使用 构造方法私有化 + 静态方法 来实现工具类,比如 Math
class Tools{private Tools(){};public static void print1(){System.out.println("工具类1执行");}public static void print2(){System.out.println("工具类2执行");}
}
//1.懒汉式: 在第一次调用getInstance方法时,对象被创建,到程序结束后释放
class Singleton1{private Singleton1() {}; //构造方法私有化private static Singleton1 s = new Singleton1();//声明一个本类对象public static Singleton1 getInstance(){return s;}//提供一个静态方法获取对象实例public void print(){System.out.println("懒汉式测试方法");}
}
//2.饿汉式: 在类被加载后,对象被创建,到程序结束后释放
class Singleton2{private Singleton2() {}private static Singleton2 s2;public static Singleton2 getInstance() {if(s2==null) {s2 = new Singleton2();System.out.println("创建饿汉式单例");}return s2;}public void print() {System.out.println("饿汉式测试方法");}
}
懒汉式测试方法
创建饿汉式单例
饿汉式测试方法
工具类1执行
工具类2执行
对象数组与管理
import java.util.Arrays;/**
对象数组与管理:使用对象数组实现多个Chicken的管理。动态数组:1、数组是一种线性数据结构2、数组不适合作删除插入等操作,适合添加,查找,遍历
*/
public class Test13 {public static void main(String[] args) {ChickenManager cm = new ChickenManager(5);//创建管理类,一次性创建五个对象cm.add(new Chicken(1,"一号",2));cm.add(new Chicken(2,"二号",1));cm.delete(2);//2号内容被删除cm.add(new Chicken(3,"三号",3));cm.update(new Chicken(3,"三号",2));//修改3号信息,年龄3改为2cm.printAll();//遍历}
}
class ChickenManager {private Chicken[] cs = null; //预设一个数组private int count = 0;       //记录当前数组的元素个数(下标) 数量计数public ChickenManager(int size){ //构造方法if(size>0){					 //判断预设的个数容量是否足够cs = new Chicken[size];  //创建鸡类对象}else{cs = new Chicken[5];}}//添加:对没有的数据添加+扩容问题public void add(Chicken c) {//添加一个对象if(count>=cs.length){//数组已满,需要扩充//算法1:扩充原来数组大小的一半  cs.length*3/2+1//算法2:扩充原来数组的一倍  cs.length*2int newLen = cs.length*2;cs = Arrays.copyOf(cs,newLen); //重新赋给 cs}//不考虑扩充cs[count] = c;count++;}//更新:对已有的数据更新+null值判断问题public void update(Chicken c){Chicken temp = find(c.getId());//查找到一个完整的鸡对象,拿到getId,getName,getAge的值if(temp!=null){				   //判断是否为空temp.setName(c.getName()); //Setter and Getter更改用户的值temp.setAge(c.getAge());}}//查找:public Chicken find(int id){for(int i=0;i<count;i++){if(cs[i].getId()==id){return cs[i];}}return null;}	//删除:遍历找出id所在位置->删除对象之后的对象向前移一位->删除最后一个为空的对象public void delete(int id){for(int i=0;i<count;i++){if(cs[i].getId()==id){//找到了要删除的对象,把该对象之后的对象向前移动一位for(int j=i;j<count-1;j++){cs[j] = cs[j+1];}//把最后一个对象赋值为空(删除)cs[count-1] = null;count--;//下标减一break;//移动结束,break跳出循环}}}//输出所有:public void printAll(){for(int i=0;i<count;i++){cs[i].print();}}
}
//表示鸡的一个类(数据对象) value object (VO)
class Chicken{private int id;private String name;private int age;public Chicken(){}//一般情况下最好保留默认的构造方法public Chicken(int id,String name,int age){this.id = id;this.name = name;this.age = age;}public void setId(int id){this.id = id;}public int getId(){return id;}public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}public void print(){System.out.println("id="+id+",name="+name+",age="+age);}
}
id=1,name=一号,age=2
id=3,name=三号,age=2
继承的基础知识
/**
继承:继承是从已有的类创建新类的过程。
继承一个父类,只能继承非私有的数据(属性和方法)
protected访问权限修饰符,在继承关系中使用,在父类中使用protected修饰的属性或方法可以被子类继承
创建子类对象时,父类的构造方法也会被调用,为什么?
因为子类要使用到父类的数据,那么就要通过父类的构造方法来初始化数据
如果创建子类对象时会调用父类的默认构造方法当父类中没有无参构造方法时,子类必须显示的调用父类的带参构造方法,怎么处理?
可以在子类中显示的使用super(...)调用父类的构造方法,只能出现在第一句面试题 :overloading与overriding的区别?
overloading:方法的重载,发生在同一个类中,方法名相同,参数列表不同,返回值无关。
overriding:方法的重写,发生在子父类中,方法名相同,参数列表相同,返回值相同,子类的访问修饰符要大于或等于父类
的访问修饰符,子类的异常声明必须小于或等于父类的异常声明。如果方法被private,static,final修饰,那么不能被重写*/
public class Test1 {public static void main(String[] args) {HomeDog homeDog = new HomeDog("旺财");homeDog.print();homeDog.eat(); //调用本身的子类,还会调用父类中的方法HuskyDog huskydog = new HuskyDog("小宝",2);huskydog.eat();}
}class Dog{protected String name;protected int age; //如果要继承需要修改成protected,不要用privatepublic Dog() {}public Dog(String name,int age) {this.name = name;this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void setAge(int age) {this.age = age;}public int getAge() {return age;}public void intro(String name,int age) {System.out.println("我是"+name+"我今年"+age+"岁,我是在父类当中被子类调用的方法");}
}class HomeDog extends Dog{public HomeDog(String name){super(name, 2);System.out.println("我是HomeDog的构造方法");}protected void print(){//super.属性 表示调用父类的属性,如果是继承过来的属性,那么super可以省略System.out.println(super.name+"我是一只家狗");}//重写父类的方法public void eat(){super.intro(name,2);//调用父类的方法System.out.println("我是家狗,我喜欢吃骨头");}
}class HuskyDog extends Dog{public HuskyDog(String name,int age) {super(name,age);System.out.println("我是HuskyDog的构造方法");}public void eat() {System.out.println("我叫"+name+"我今年"+age+"岁,我特别能吃");}
}
我是HomeDog的构造方法
旺财我是一只家狗
我是旺财我今年2,我是在父类当中被子类调用的方法
我是家狗,我喜欢吃骨头
我是HuskyDog的构造方法
我叫小宝我今年2,我特别能吃
继承的应用示例
/**继承的应用示例:化妆品商城中的化妆品管理
*/
public class Test2 {public static void main(String[] args) {ImportCosmeticManager cm = new ImportCosmeticManager();SortCosmeticManager sc = new SortCosmeticManager();System.out.println("下方输出的是进口的化妆品:");cm.add(new Cosmetic("香奈儿","进口",1000));cm.add(new Cosmetic("圣罗兰","进口",800));cm.add(new Cosmetic("大宝","国产",20));cm.add(new Cosmetic("万紫千红","国产",15));cm.printInfo();System.out.println("下方输出的按照单价进行排序的化妆品(升序):");sc.add(new Cosmetic("大宝","国产",20));sc.add(new Cosmetic("万紫千红","国产",15));sc.printInfo();}
}
//可输出进口化妆品的管理类,非进口无法输出--->过滤
class ImportCosmeticManager extends CosmeticManager{public void printInfo(){//比较两个字符串的值是否相等,不能使用==,使用equals()for(int i=0;i<count;i++){if("进口".equals(cs[i].getType())){//拿到化妆品的类型并与之匹配System.out.println(cs[i].getInfo());}}}
}
//可按单价排序的化妆品管理类
class SortCosmeticManager extends CosmeticManager{//排序输出所有产品public void printInfo(){Cosmetic[] temp = java.util.Arrays.copyOf(cs,count);//将排序好的数组放在一个新数组当中Cosmetic c = null;//创建一个空对象,中间值辅助对象中的替换for(int i=0;i<temp.length-1;i++){for(int j=0;j<temp.length-i-1;j++){if(temp[j].getPrice()>temp[j+1].getPrice()){c = temp[j];temp[j] = temp[j+1];temp[j+1] = c;}}}for(Cosmetic cosmetic: temp){System.out.println(cosmetic.getInfo());}}
}
//化妆品管理类
class CosmeticManager{protected Cosmetic[] cs  = new Cosmetic[4];protected int count = 0;//计数//进货功能public void add(Cosmetic c){int size = cs.length;if(count>=size){int newLen = size*2;cs = java.util.Arrays.copyOf(cs,newLen);}cs[count] = c;count++;}//输出所有产品public void printInfo(){for(int i=0;i<count;i++){System.out.println(cs[i].getInfo());}}}
//化妆品类
class Cosmetic{private String name;//品牌private String type;//进口或国产private int price;  //单价public Cosmetic(){}public Cosmetic(String name,String type,int price){this.name = name;this.type = type;this.price = price;}public void setName(String name){this.name = name;}public String getName(){return name;}public void setType(String type){this.type = type;}public String getType(){return type;}public void setPrice(int price){this.price = price;}public int getPrice(){return price;}public String getInfo(){return "name="+name+",type="+type+",price="+price;}
}
下方输出的是进口的化妆品:
name=香奈儿,type=进口,price=1000
name=圣罗兰,type=进口,price=800
下方输出的按照单价进行排序的化妆品:
name=万紫千红,type=国产,price=15
name=大宝,type=国产,price=20
final关键字
/**
final关键字:1、使用final声明一个属性,就是常量,常量的命名规则建议使用全大写,常量必须在定义时或在构造器中初始化2、使用final声明的方法,不能被子类重写,只能被继承3、使用final关键字声明一个类,该类就转变为最终类,没有子类的类,fianl修饰的类无法被继承。
*/
public class Test3{public static void main(String[] args){System.out.println("获取final类中的数据: "+Constant.PERSON_NUM);//10FinalClass fc = new FinalClass();fc.setLength(10);}
}//常量类(工具类):在实际项目开发中,常量类通常用于定义项目中一些公共的,不变的,数据final class Constant{public static final int PERSON_NUM = 10; //人数public static final String SERVER_ROOT_URL = "http://www.baidu.com";public static final String CACHE_PATH = "data_cache";}class FinalClass{public final int DAY_NUMBER;//工作天数public FinalClass(){DAY_NUMBER = 22;}public final void print(){System.out.println("我是final方法");}public void setLength(final int size){//final int x = 20; //size.++;因为参数是final修饰,所以不能修改size值System.out.println(size);}}class SubClass extends FinalClass{/*public void print(){System.out.println("我是final方法");}*/
}
获取final类中的数据: 10
10
抽象类
/** 抽象类: ① 用abstract关键字声明的类称为抽象类*/
public class Test4 {public static void main(String[] args) {// 将继承的"人类"类进行实例化Person p1 = new Person();p1.sleep();p1.move();//		Animal a = new Animal(); ② 抽象类不能被实例化:报错}}abstract class Animal{//抽象类不能被实例化public Animal() {};// ③ 抽象类可以有构造方法public abstract void move();//④ 抽象方法: 方法的声明,抽象方法只有声明,没有实现
} //抽象类// ⑤ The class staff can be either abstract or final, not both
// 在 abstract 与 final 之间只能选一个/*final abstract class staff{public abstract void lay();
}*/// ⑥ 继承的抽象类,可以不实现父类抽象方法
abstract class Cat extends Animal{public abstract void eat();public void speak() {System.out.println("我会说话");};
}class Person extends Animal{@Override//重写public void move() {System.out.println("我是普通类中的移动方法");};// ⑦ 非抽象类继承抽象类必须实现所有抽象方法public void sleep() {System.out.println("我是普通类中的睡觉方法");};}
我是普通类中的睡觉方法
我是普通类中的移动方法
接口
package com.jf.java4;
/** 接口*/
public class Test5 {public static void main(String[] args) {Girl g1 = new Girl("Rose");// Girl类当中的三个方法g1.run();g1.eat();g1.sleep();// 通过 Girl 类来调用接口中 IEat 的 print() 方法g1.print();}}
//接口一:
interface IEat{
//	public abstract void eat();  接口中只能定义抽象方法void eat(); // 等同于上方的抽象方法public final int NUM = 10; //定义常量//在JDK1.8后新特性,可以被所有实现类继承public default void print(){System.out.println("接口里的打印方法被调用");}
}interface IRun{void run();
}//接口二:
//接口之间可以多继承(注意:类是只能单继承)
interface ISleep extends IEat,IRun{void sleep();
}//具体类实现接口必须实现接口的所有方法
class Girl implements IEat,IRun{private String name;public Girl(String name){this.name = name;}@Overridepublic void run() {System.out.println("我是"+name+",我爱跑步");}@Overridepublic void eat() {System.out.println("我是"+name+",我爱睡觉");}public void sleep() {System.out.println("我是"+name+",我爱吃");}}
我是Rose,我爱跑步
我是Rose,我爱睡觉
我是Rose,我爱吃
接口里的打印方法被调用
多态性
/** 多态性:对象在运行过程中的多种状态*/
public class Test6 {public static void main(String[] args) {//用父类的引用指向子类对象(用大的类型来表示小的类型),自动转换(向上转型)//实例对象类型是父类Chicken,创建对象时可以指向一个由父类继承的子类Chicken dc = new DomesticChicken("家鸡");Chicken p = new Pheasant("野鸡");Chicken h = new Hen("母鸡");dc.eat();eat(dc);p.eat();eat(p);h.eat();// h.song(); 此时这里是报错的,因为song并不是属于鸡类的抽象方法无法调用eat(h);System.out.println("------------------------");//此时就可以调用母鸡的Song方法Hen hen = new Hen("母鸡二号");hen.song();}//抽象(粒度) 面向抽象编程(面向接口编程)public static void eat(Chicken c){System.out.println("输出:");c.eat();//当我们需要把父类的实例强制转换为子类引用时,为了避免类型转换异常 java.lang.ClassCastException//那么我们需要在转换之前作类型检查(判断)if(c instanceof Hen){ //成立的条件是,对象本身及对象的父类型,都可以通过检查Hen hen = (Hen) c; //大的类型转换为小的类型,强制转换(向下转型)hen.song();}}
}//鸡抽象类
abstract class Chicken{private String name;public Chicken(){}public Chicken(String name){this.name = name;}public void setName(String name){this.name = name;}public String getName(){return name;}public abstract void eat();
}
//家鸡
class DomesticChicken extends Chicken{public DomesticChicken(String name){super(name);}public void eat(){System.out.println(this.getName()+",我爱吃米");}
}
//野鸡
class Pheasant extends Chicken{public Pheasant(String name){super(name);}public void eat(){System.out.println(this.getName()+",我爱吃虫子");}
}
//母鸡
class Hen extends Chicken{public Hen(String name){super(name);}public void eat(){System.out.println(this.getName()+",我不吃东西");}public void song(){System.out.println("我是母鸡,我爱唱歌");}
}
家鸡,我爱吃米
输出:
家鸡,我爱吃米
野鸡,我爱吃虫子
输出:
野鸡,我爱吃虫子
母鸡,我不吃东西
输出:
母鸡,我不吃东西
我是母鸡,我爱唱歌
------------------------
我是母鸡,我爱唱歌
父类的设计法则

父类一般是抽象类或接口,优先考虑接口,接口不满足再考虑抽象类

模板方法模式
/**
模板方法模式 (Templete Method)
*/
public class Test7{public static void main(String[] args){UserManager um = new UserManager();um.action("admin","del");}
}abstract class BaseManager{//验证操作public void action(String name,String method){if("admin".equals(name)){execute(method); //封装执行动作(子类)}else{System.out.println("你没有操作权限,请联系管理员");}}public abstract void execute(String method); //抽象方法
}//子类封装一个固定的算法
class UserManager extends BaseManager{public void execute(String method){ //实现抽象类中的抽象方法//用户是否登录的验证//验证成功后的执行操作if("add".equals(method)){System.out.println("执行了添加操作");}else if("del".equals(method)){System.out.println("执行了删除操作");}}
}
策略设计模式
/** 策略模式(Strategy Pattern):* 定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,* 策略模式让算法独立于使用它的客户应用而独立变化。*/public class Test8 {public static void main(String[] args) {BaseService user = new UserService();user.setISave(new FileSave());user.add("user");}}//把可变的行为抽象出来,定义一系列的算法
interface ISave{public void save(String data);
}
//用接口的方式来模拟两种方式存储
class FileSave implements ISave{public void save(String data){System.out.println("把数据保存到文件中..."+data);}
}
class NetSave implements ISave{public void save(String data){System.out.println("把数据保存到网络上..."+data);}
}
abstract class BaseService{//更改的是接口的类型:当前是FileSave(),ISave的类型File Save()private ISave iSave;//私有化一个接口public void setISave(ISave iSave){this.iSave = iSave;}//setter 定执行模式,文件保存还是网络保存public void add(String data){System.out.println("检查数据合法性...");iSave.save(data);//往接口里操作,根据储存的接口选择相对应接口System.out.println("数据保存完毕。");}
}//存储数据
class UserService extends BaseService{} //使用继承的子类来调用父类当中的方法
检查数据合法性...
把数据保存到文件中...user
数据保存完毕。
Object对象
/** Object对象:类层次结构下的根类*/
public class Test9 {public static void main(String[] args) {Student s1 = new Student(1,"Felix",23);Student s2 = new Student(1,"Felix",23);String str1 = s1.toString();System.out.println(str1);boolean boo = s1.equal(s2);System.out.println("比较s1和s2的结果是:"+boo); //trueString str2 = new String("备备");String str3 = new String("备备");//equals是表示比较两个对象内存地址是否相等System.out.println(str2.equals(str3));//true//表示基本类型时是比较值//比较引用类型时是内存地址是否相同System.out.println(s1.getClass()==s2.getClass());//true}
}class Student{private int sid;private String name;private int age;public Student() {};public Student(int sid, String name, int age) {this.sid = sid;this.name = name;this.age = age;}public int getId() {return sid;	}public String getName() {return name;}public int age() {return age;}//重写Object类中的toString()方法@Overridepublic String toString() {return "学号:"+sid+" 姓名:"+name+" 年龄:"+age;}//重写equals方法,来实现两个对象的比较/** 实现相等关系:* 自反性: x.equals(x) 返回 true* 对称性: x.equals(y) y.equals(x) 返回 true* 传递性: x.equals(y) y.equals(z) x.equals(z) 返回 true* 一致性: x.equals(y) 始终返回 true 或 false* 对于非空引用值返回false*/public boolean equal(Object obj) {if(this==obj) {return true;}if (obj instanceof Student) {Student s = (Student) obj;if(!this.name.equals(s.name)){return false;}if(this.sid!=s.sid){return false;}if(this.age!=s.age){return false;}return true;}return false;}
}
简单工厂模式
package com.jf.java4;
/** 简单工厂模式: 是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。*/
public class Test10 {public static void main(String[] args) {//使用者和被使用者两者之间,耦合,产生了依赖,当被使用者改变时,会影响使用者//使用工厂模式来降低两者之间的依赖//		Product phone = new Phone(); //创建实例对象:如果要启动Computer,就必须要更改创建一个新的对象Computer
//		phone.work();//更改为工厂模式后,只要更改输入的产品就可以创建相应的对象Product computer = ProductFactory.getProduct("computer");if(null!=computer){  //输入的产品不能为空,为空不能进行执行computer.work(); //开始执行}else {System.out.println("没有此类产品");}}
}
//工厂类
class ProductFactory{public static Product getProduct(String name) {//静态方法if(name.equals("phone")) {return new Phone();    //创建实例对象} else if (name.equals("computer")){return new Computer(); //创建实例对象}return null;}
}interface Product{public void work();
}class Phone implements Product{public void work() {System.out.println("手机开始工作....");}
}class Computer implements Product{public void work() {System.out.println("电脑开始工作....");}
}
电脑开始工作....
代理模式
/** 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。* 代理模式说白了就是“真实对象”的代表,在访问对象时引入一定程度的间接性,* 因为这种间接性可以附加多种用途。*/
public class Test11 {public static void main(String[] args) {//可以写n个事件,交给ActionProxy进行代理执行Action userAction = new UserAction();//创建一个事件ActionProxy proxy = new ActionProxy(userAction);//代理这个事件proxy.doAction();//开始计时}
}interface Action{public void doAction();
}class ActionProxy implements Action{private Action target;//被代理的对象public ActionProxy(Action target){//传入的是这个事件对象this.target = target;}//执行操作public void doAction(){long startTime = System.currentTimeMillis();//开始时间target.doAction();//执行真正的业务long endTime = System.currentTimeMillis();//结束时间System.out.println("共耗时:"+(endTime-startTime));}
} class UserAction implements Action{public void doAction(){for(int i=0;i<5;i++){System.out.println("用户开始工作...");}}
}
用户开始工作...
用户开始工作...
用户开始工作...
用户开始工作...
用户开始工作...
共耗时:0
适配器模式
/*适配器模式: 使原本两个不兼容的接口也可以一起工作 -> 转接头*/
public class Test12 {public static void main(String[] args) {PowerA powerA = new PowerAImp1();work(powerA);//适配器让原先不能在PowerA当中运行的PowerB也能工作PowerB powerB = new PowerBImp1();Adapter adapter = new Adapter(powerB);work(adapter);AnimalFunction af = new Dog();af.run();}public static void work(PowerA a) {System.out.println("工作开始");a.insert();System.out.println("工作结束");}
}
// 适配器让两个互不干扰的两个接口也可以一起工作
class Adapter implements PowerA{private PowerB powerB;public Adapter(PowerB powerB){this.powerB = powerB;}public void insert(){powerB.connect();}
}
// 原本的A和B的内部不发生变化
interface PowerA{public void insert();
}
interface PowerB{public void connect();
}
class PowerAImp1 implements PowerA{public void insert() {System.out.println("电源A开始工作");}
}
class PowerBImp1 implements PowerB{public void connect() {System.out.println("电源B开始工作");}
}
//适配器第二种写法
abstract class AnimalFunction{public void sing(){};public void run(){};public void eat(){};
}class Dog extends AnimalFunction{public void run(){System.out.println("我是狗, 我能跑");}
}
工作开始
电源A开始工作
工作结束
工作开始
电源B开始工作
工作结束
我是狗, 我能跑
内部类
/*内部类: 内部类有效实现了"多重继承"(因为java的继承只能单继承,虽然接口可以多继承,但是不可以实例化对象)*/
public class Test13 {public static void main(String[] args){// ① 成员内部类:直接在类中定义的类Outer outer = new Outer();// 不建议这样实例化对象:// outer.Inner inner = outer.new Inner();// inner.print();outer.InnerPrint();// 成功激活成员内部类// ② 方法内部类:在方法中定义的类outer.doSomething();// ③ 静态内部类:在类中定义静态内部类Outer.Inner3 inner3 = new Outer.Inner3();inner3.print();// ④ 匿名内部类// 继承式:outer.print1();// 接口式:outer.print2();// 参数式:outer.print3(new IEat() {@Overridepublic void eat() {System.out.println("我是参数式的匿名内部类");}});}
}class Outer{private String name;// 建议在对成员内部类提供一个对外访问的方法public void InnerPrint(){Inner inner = new Inner();inner.print();}// 成员内部类private class Inner{public void print(){System.out.println("成员内部类");}}// 方法内部类public void doSomething(){final int x = 10;// JDK1.8之后取消// final 修饰让常量池内的数据停留的时间更长,否则一旦局部变量弹栈即消失,但是调用还需要这个值,所以要延长生命周期class Inner2{public void print(){System.out.println("方法内部类 "+x);// 从内部类引用的变量必须是一个定值或者说是一个最终变量}}Inner2 inner2 = new Inner2();inner2.print();}static class Inner3{// 无法从静态上下文中用非静态变量public void print(){System.out.println("静态内部类");}}// 匿名内部类// 继承式public void print1(){Cat cat = new Cat(){public void eat() {System.out.println("我是继承式匿名内部类");}};cat.eat();// 调用方法}// 接口式public void print2(){IEat eat = new IEat(){public void eat(){System.out.println("我是接口式匿名内部类");}};eat.eat();// 调用方法}// 参数式:不能定义任何静态成员、静态方法public void print3(IEat eat){eat.eat();}
}abstract class Cat{public abstract void eat();
}interface IEat{public void eat();
}
成员内部类
方法内部类 10
静态内部类
我是继承式匿名内部类
我是接口式匿名内部类
我是参数式的匿名内部类

如何选择内部类:
① 依赖外部类对象的,成员内部类,方法内部类,匿名内部类
② 静态内部类不依赖外部类的对象
在项目中优先考虑选择静态内部类(内存泄露)

递归算法
/*
递归算法:能不用就不用*/
class Test14{public static void main(String[] args){int Fac = Factorial1(10);System.out.println(Fac);int Fac2 = Factorial2(10);System.out.println(Fac2);}public static int Factorial1(int num){int result = num;int i = num - 1;do {result = result * i;i--;}while(i>1);return result;}// 递归算法:方法本身调用自己// 1. 递归必须要有出口// 2. 递归内存消耗大, 容易发生了内存溢出// 3. 层次使用越多, 越危险public static int Factorial2(int num){if(num==1){return 1;}return num*Factorial2(num-1);}
}
链表
/*
链表: 是一个数据结构, 是一种线性表, 但不按照线性循序存储数据存放每一个节点下存在下一节点的指针(pointer)链表与数组, 线性数据结构数组适合查找, 遍历, 固定长度链表适合插入, 删除, 不宜过长, 否则会导致遍历性能下降有一点儿难度, 需要反复练习*/
public class Test15 {public static void main(String[] args) {NodeManager nodeManager = new NodeManager();nodeManager.add(5);nodeManager.add(4);nodeManager.add(3);nodeManager.add(2);nodeManager.add(1);nodeManager.del(1);nodeManager.update(4, 10);boolean bool = nodeManager.find(3);System.out.println(bool);nodeManager.insert(3,20);nodeManager.print();}
}
class NodeManager{private Node root; // Private Node root = new Node(data) 创建一个实例对象private int currentIndex; // 节点的序号, 每次操作从零开始public void add(int data){if(root==null){root = new Node(data);}else{root.addNode(data); // 不为空的节点, 添加一个节点(原先的一个节点 + 更新后的节点)}}public void del(int data){if(root.getData()==data){root = root.next; // 当删除这个节点之后, 后一个位置需要顶上来}else{root.deleteNode(data); // 递归}}public void print(){if(root!=null){System.out.print(root.getData()+"->");root.printNode();System.out.println();}}public boolean find(int data){if(root==null){return false;}if(root.getData()==data){return true;}else{return root.findNode(data);}}public boolean update(int oldData, int newData){if(root==null){return false;}if(root.getData()==oldData){root.setData(newData);return true;} else{return root.updateNode(oldData,newData);}}public void insert(int index, int data){if(index<0){return;}if(index==currentIndex){Node newNode = new Node(data);newNode.next = root;root = newNode;}else{root.insertNode(index,data);}}private class Node{private int data;private int Node;private Node next; //把当前类型作为属性public Node(int data){this.data= data;}public void setData(int newData){this.data = data;}public int getData(){return data;}// 添加节点public void addNode(int data){if(this.next==null){this.next = new Node(data); // 如果下一个节点为空, 创建一个新对象, 等待存储}else{this.next.addNode(data); // 如果下一个节点不为空, 添加一个数据, 进行递归处理}}// 删除节点public void deleteNode(int data){if(this.next!=null){if(this.next.data==data){this.next = this.next.next;}else{this.next.deleteNode(data);}}}// 打印节点public void printNode(){if(this.next!=null){System.out.print(this.next.data+"->");this.next.printNode();}}// 查询节点public boolean findNode(int data){if(this.next!=null){if(this.next.data==data){return true;}else{return this.next.findNode(data);}}return false;}// 更新节点public boolean updateNode(int oldData, int newData){if(this.next!=null){if(this.next.data==oldData){this.next.data = newData;return true;}else{return this.next.updateNode(oldData, newData);}}return false;}// 插入节点public void insertNode(int index, int data){currentIndex++;if(index==currentIndex){Node newNode = new Node(data);newNode.next = this.next;this.next = newNode;}else{this.next.insertNode(index,data);}}}
}
true
5->10->3->20->2->
包与访问修饰符

定义一个包:
package com.vince;

访问修饰符权限:

访问修饰符同一个类同一个包不同包子类不同包非子类
public
protected
default
private

视频链接 -> 笔记摘抄 + 理解整理

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/101591.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息