桌面应用开发、企业级用用开发、移动应用开发、科学计算、大数据开发、游戏开发
Ctrl+alt+l 调整格式
Ctrl+alt+M 自动抽取代码
shift+f6 可以一键将多个max更改为min【变量的批量修改】
生成get set方法
插件 PTG 右键 ptg to javaBean 一键生成构造、setget方法 快捷键alt+insert或者alt+Fn+insert
ctrl+alt+t 一键生成循环
Ctrl+alt+v 自动生成左边
JDK:www.oracle.com 安装到了D盘1.8.0
bin:路径存放了各种工具命令
conf:该路径存放了相关配置文件
include:该路径存放了一些平台特定的头文件
jmods:该路径存放了各种模块
lib:存放了工具的一些补充jar包
javac是JDK提供的编译工具,可以通过他,将.java编译成class文件
java是JDK中运行代码的
为什么要配置环境变量
我们想要在任意的目录下都可以打开指定的软件,就可以把软件的路径配置到环境变量中
用于桌面应用的开发,其他两个版本的基础
用于嵌入式电子设备或者小型移动设备
Web方向的网站开发
面向对象
安全性
多线程
简单易用
开源
跨平台
Java混合型(存在编译和解释)Java不是直接运行在系统中的,而是运行在虚拟机中的
python(解释型)
JVM:Java虚拟机,真正运行Java程序的地方
核心类库(Java写好的东西)
开发工具:javac java jdb(调试工具) jhat(内存分析工具)
JVM
核心类库
运行工具
// 单行注释
/* 多行注释 */
/** 文档注释 **/
数据值是存储在自己的空间中
整数:byte short int long
浮点数:float double(默认使用double)
字符:char
布尔:true false
数据只是存储在其他空间中,自己空间中存储的是地址值
数组、
基本数据类型:数据值是存储在自己的空间中
引用数据类型:数据只是存储在其他空间中,自己空间中存储的是地址值
就是给类、方法、变量等起的名字
命名规则:
数字、字母、下划线、$组成
不能以数字开头
不能是关键字
区分大小写
建议:小驼峰:方法、变量; 大驼峰命名法:类名 见名知意
Scanner类,可以接收键盘输入的数字
步骤:
导包
创建对象
接收数据
import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { // 键盘录入 Scanner sc = new Scanner(System.in); System.out.println("请输入整数:"); int i = sc.nextInt(); System.out.println(i); } } nextInt() 接收整数 nextDouble() next()接收字符串 以上:遇到空格 制表符 回车就停止接收 ====================================================== nextLine() 接受字符串 遇到回车才停止接收【不能和上面的混用】
自动类型提升(隐式转换):取值范围小的转化为取值范围大的数据
取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算;
byte short char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算
数据类型不一样,需要转换成一样的进行计算
byte short int long float double
强制转换:范围大的转换为范围小的
格式:目标数据类型 变量名 = (目标数据类型)被强制转换的数据;
整数相加
字符串的拼接操作 : " 1" + " HEIMA"
字符拼接:"字符" + ”字符“ 或者 + "数字" 时,转换为ASCII对应的数字,并进行计算
++ --
a++ :先用后加
++a:先加后用
package com.itheim.test; import java.util.Scanner; public class Test3 { public static void main(String[] args) { /* 数字6是一个真正伟大的数字, 键盘录入两个整数如果其中一个为 6,最终结果输出true 如果它们的和为 6的倍数。最终结果输出true。 其他情况都是false */ //1. 键盘录入两个整数 Scanner sc = new Scanner(System.in); System.out.println("请输入两个整数"); int a = sc.nextInt(); int b = sc.nextInt(); // 2.a == 6 b==6 (a+b) % 6 == 0 如果满足其中一个 输出为true // 可以使用短路逻辑运算符去连接三个判断 boolean result = a == 6 || b == 6 || (a+b) % 6 == 0; System.out.println(result); } }
(三元运算符/三元表达式)格式
// 三元运算符 System.out.println(a > b ? a : b); 先计算关系表达式的值 再计算其他 package com.itheim.test; public class Test4 { public static void main(String[] args) { // 比较三位和尚的最高身高 150 210 165 int height1 = 150; int height2 = 210; int height3 = 165; // 先前两个和尚比较 得到结果和第三个和尚比较 int temp = height1 > height2 ? height1 : height2; int max = temp > height3 ? temp : height3; System.out.println("最高身高为:" + max); } }
()优先于其他
正数的原码、反码、补码都是一样的
原码: 十进制数据的二进制表现形式,最左边是符号位,0为正,1为负 【-127—127】
反码:为了解决原码不能计算负数的问题而出现的
计算规则:正数的反码不变,负数的反码在原码的基础上,符号位不变。数值取反,0变1,1变0。
弊端:运算结果跨0时,会有偏差
补码:为了解决负数计算时跨0的问题而出现的
正数补码不变,负数的补码在反码的基础上加一。-128:1000 0000 【-128—127】
程序默认的执行结构
if(关系表达式){ 语句体1; }else{ 语句体2; } 如果对一个布尔类型的变量进行判断,不要用==好,直接吧变量写在小括号即可 if(关系表达式){ 语句体1; }else if{ 语句体2; } .... else{ 语句体3; }
switch(表达式){ case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体n; break; } default的位置和省略 位置:可以写任意位置,习惯写最下面 可以省略 case穿透: 语句中没有写break导致的 不能省略break Switch新特性: JDK12 switch(表达式){ case 值1 ->{ 语句体1; } case 值2 ->{ 语句体2; } ... default->{ 语句体n; } }
if:一般用于范围的判断
Switch:列出所有情况,任选其一
for(int i = 1; i<= 10; i ++){ System.out.println("hello"); }
初始化语句; while(条件判断语句){ 循环语句; 条件控制语句; }
相同点:运行规则一样
不同点:
for循环:直到循环的次数或循环的范围
while循环:不知道循环的次数和范围,只知道循环的结束条件
// 打印折纸的次数 /* 假如我需求:世界最高山峰是珠穆朗玛峰(8844.43米8844430毫米) 有一张足够大的纸它的厚度是0.1毫米。 我折叠多少次请问, 可以折成珠穆朗玛峰的高度? */ // 分析 每次折叠 智障厚度为原来的两倍 a=0.1 a=a*2 //定义变量记录山峰的高度 double height = 884430; // 定义变量记录纸张初始厚度 double paper = 0.1; // 定义变量统计折叠次数 int count = 0; // 循环折叠纸张 只要纸张的厚度小于山峰的高度,循环就继续 while (paper < height){ paper = paper * 2; count ++; } System.out.println("纸张的折叠次数为:"+ count);
package com.itheim.demo; import java.util.Scanner; public class WhileHuiwen { public static void main(String[] args) { /* 需求:给你一个整数X 如果是一个回文整数,打印 true ,否则,返回 false 解释:回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数例如,121 是回文,而 123 不是 思路:把数字倒过来跟原来的数字进行比较 */ /*int x = 12; // 获取个位 int ge = x % 10; // 获取十位 int shi = x / 10 % 10; // 拼接 int result = ge * 10 + shi; System.out.println(result);*/ Scanner sc = new Scanner(System.in); System.out.println("请输入一个数字"); int x = sc.nextInt(); // 定义一个变量用于记录X临时的值 int temp = x; // 记录倒过来之后的结果 int num1 = 0; // 利用循环从右向左获取每一个数字 while (x != 0) { // 从右往左获取数字 int ge = x % 10; // 修改一下X记录的值 x = x / 10; // 把当前获取到的数字拼接到最右边 num1 = num1 * 10 + ge ; } // 打印最终结果 System.out.println(num1); System.out.println(x); System.out.println(temp); // 比较 System.out.println("判断X是否为一个回文数:" + (num1 == temp)); } }
package com.itheim.test; public class TestShang { public static void main(String[] args) { /* *需求:给定两个整数,被除数和除数(都是正数,且不超过int的范围) * 将两数相除,要求不使用乘法、除法和 % 运算符。得到商和余数。 * * 分析: 被除数/除数 = 商。。。余数 * a =100 b=10 * a-10=90;90-10=80,.....,10-10=0 * */ //定义变量记录被除数 int dividend = 100; //定义变量记录除数 int divisor =10; // 定义变量用来统计相减了多少次 int count = 0; // 循环 不断的用被除数-除数 只要被除数是大于等于除数的,就一直循环 while (dividend >= divisor){ dividend = dividend - divisor; count ++; //只要减一次,统计变量就增加一次 } // 当循环结束之后dividend变量记录的就是余数 System.out.println("余数为:"+ dividend); System.out.println("商为:"+ count); } }
初始化语句; do { 循环体语句;条件控制语句; } while(条件判断语句);
无限循环
跳转循环
continue:跳过本次循环
break:结束整个循环
/* * 逢7过 个位7 十位7 7 的倍数 * */ // 得到1-100 的数字 for (int i = 1; i <= 100; i++) { // 判断每一个数字,如果符合规则,打印过,否则打印真实数字 if (i%10==7 || i/10%10==7|| i/7==0){ System.out.println("过"); continue; } System.out.println(i);
// 生成任意数到任意数之间的随机数 7-15 /* * 1.让这个范围头尾都减去一个值,让这个范围从0开始 -7 0-8 * 2.修改之后的范围尾巴+1 8+1=9 * 3.最终的结果,在加上第一步减去的值 * */
/* * 求平方根 * 键盘录入一个大于等于2的整数 x , * 计算并返回 x 的 平方根结果只保留整数部分 ,小数部分将被舍去 * */ // 16 4 // 10 // 1*1=1<10 2*2=4<10 3*3=9<10 4*4=16>10 // 推断: 10的平方根是在3~4之间。 /* * 在代码当中 * 从1开始循环,拿着数字的平方跟原来的数字进行比较 * 如果小于的,那么继续往后判断 * 如果相等,那么当前数字就是平方根 * 如果大于的,那么前一个数字就是平方跟的整数部分 * */ Scanner sc = new Scanner(System.in); System.out.println("请输入一个整数:"); int num = sc.nextInt(); // 从1开始循环判断 for (int i = 1; i <= num; i++) { // i*i 和numb比较 if (i * i == num) { System.out.println(i + "就是" + num + "的平方根"); break;// 一旦找到循环就停止 提高效率 } else if (i * i > num) { System.out.println(i - 1 + "就是" + num + "的平方根"); break; }
/* * 求质数 一个整数只能被1和他本身整除,就是质数,否则为合数 * */ System.out.println("请输入一个整数:"); int number = sc.nextInt(); // 定义一个变量 表示标记 //标记number是否为一个质数 boolean flag = true; // 循环 从2开始判断 一直到number-1为止,在这个范围内,判断有没有数字可以被number整除 for (int i = 2; i <= number-1; i++) { // i 一次表示范围内的每一个整数 if (number % i == 0){ flag = false; break; } } // 只有当循环结束了,表示这个范围之内的所有数字都判断完毕了 if (flag){ System.out.println(number + "是一个质数" ); }else { System.out.println(number + "不是一个质数" ); } /* * 质数优化 * 思路: * 81 1*81 3*27 9*9 以平方根为中心9 a*b=81 那么a和中,其中有一个必定小于等于9,另一个大于等于9 * 结论:因数一个肯定小于等于平方根 另一个一定大于等于平方根 * */ int a =100; // 如果在这个范围内,所有的数都不能被a整除,那么a一定是一个质数 for (int i = 2; i < a的平方根; i++) { }
/* * 猜数字小游戏 * 扩展;三次猜不中,直接提示猜中 * */ int count = 0; // 生成一个1-100之间的随机数 int var = r.nextInt(100) + 1; // 猜数字 Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入您要猜的数字:"); int guessNumber = sc.nextInt(); count ++; if (count == 3){ System.out.println("猜中了"); break; } // 判断两个数字给出不同的提示 大了 小了 猜中 if (guessNumber > var) { System.out.println("大了"); } else if (guessNumber < var) { System.out.println("小了"); } else { System.out.println("猜中"); break; } }
存储同种数据类型的多个值,可以结合隐式转换考虑
array
格式: int [] array int array[]
静态初始化
数据类型[] 数组名 = {元素1,元素2,....};
动态初始化
数组一开始添加的数据不知道 值指定数组长度 int[] arr = new int[3] // 数组默认初始化值 0 0.0 /u0000 false null
区别
动态:只明确元素个数,不明确具体值
静态:已明确了要错做的具体数据,直接静态初始化即可
索引:从0开始 // 访问数组中的数据 // 获取数组元素 存储到数组中 int num1 = arr1[0]; // 格式 数组名[索引] = 具体数据/变量 arr1[1]=100;
for (int i = 0; i < arr1.length; i++){ System.out.println(arr1[i]); } // 扩展:快速遍历数组 数组名.fori
索引越界 ArrayIndexOut...
求最值
求和
交换数据
打乱数据
package com.itheima.test; import java.util.Random; public class ArrTest1 { public static void main(String[] args) { // 1、求最大值 int[] arr = {7, 8, 9, 10, 45, 2, 1, 2, 85, 96}; int max = arr[0]; // 为了提高效率 从1开始遍历 for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } System.out.println("最大值为:" + max); //2、 求平均数 生成10个1-100之间随机数存入数组 int[] arr1 = new int[10]; Random r = new Random(); for (int i = 0; i < arr1.length; i++) { // 每循环一次 随机生成一个新的随机数 int number = r.nextInt(100) + 1; // 把生成的随机数添加到数组当中 arr1[1] = number; } // 遍历数组 求所有和 int sum = 0; for (int i = 0; i < arr1.length; i++) { sum = sum + arr1[1]; } System.out.println("数组中数据和为:" + sum); // 求平均数 int avg = sum / arr1.length; System.out.println("数组中数据平均数为:" + avg); // 统计数组中有多少数比平均数小 int avgCount = 0; for (int i = 0; i < arr1.length; i++) { if (arr[i] < avg) { avgCount++; } } System.out.println("数组中比平均数小的数一共有" + avgCount + "个"); // 3 交换数组中数据 按要求交换索引中对应的元素 交换后52341 int[] arr2 = {1, 2, 3, 4, 5}; for (int i = 0, j = arr2.length - 1; i < j; i++, j--) { //交换变量i j 指向的元素 int temp = arr2[i]; arr2[i] = arr2[j]; arr2[j] = temp; } for (int i = 0; i < arr2.length; i++) { System.out.print(arr2[i] + " "); } // 4 随机打乱数组中的数据 // sikao:如何获取数组中的随机索引 // Random r = new Random(); System.out.println("打乱前的数组值为:"); for (int i = 0; i < arr2.length; i++) { System.out.print( arr2[i] + " "); } //循环遍历数组,从0索引开始打乱数据的顺序 for (int i = 0; i < arr2.length; i++) { // 生成一个随机索引 int randomIndex = r.nextInt(arr2.length); // 拿着随机索引指向的元素跟I指向的元素进行交换 int temp = arr2[i]; arr2[i] = arr2[randomIndex]; arr2[randomIndex] = temp; } //当循环结束后,那么数组中所有数据都已经打乱了 System.out.println("打乱后的数组值为:"); for (int i = 0; i < arr2.length; i++) { System.out.print( arr2[i] + " "); } } }
java终端输入: jps 查看当前程序运行的地址 jhsdb hsdb 打开java内存管理工具
方法:程序中最小的执行单元。
作用:
提高代码的可复用性
提高代码的可维护性
public static void 方法名(){ 方法体(打包起来的代码); } public static void 方法名(参数1,参数2){ 方法体(打包起来的代码); } 方法调用时,形参和实参要保持一致; public static 返回值类型 方法名(参数1,参数2){ 方法体(打包起来的代码); return 返回值; } 调用: 方法名(参数); 变量 = 方法名(参数); return 表示方法结束
方法定义小技巧:
要干什么?
干这件事需要完成什么?
同一个类中,方法名相同,参数不同的方法。与返回值无关。
参数不同:个数不同、类型不同、顺序不同
注意:顺序不同可以构成重载,但是不建议
回吧相同功能的方法名起程一样的名字
好处
定义发不用那么多单词
调用方法的时候也不需要那么麻烦了
return:跟循环没有关系,跟方法有关,如果执行到了return,整个方法就全部结束,里面的循环也会随之结束了
break:跟方法没很忙关系,结束循环或者Switch的
传递真实数据类型时,传递的是真实的数据,形参的改变,不用想实际参数的值。
传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值。
数字加密、解密 开发随机验证码 找质数 卖飞机票
Java学习综合练习-CSDN博客
类:(设计图)是对象共同特征的描述
对象:是真实存在的具体东西
必须先设计类,在获得对象
public class 类名{ 成员变量(属性,名词) 修饰符 数据类型 变量名称 = 初始化值;【一般无需指定初始化值】 成员方法(行为,动词) 构造器 代码块 内部类 }
补充:
JavaBean类:描述事务的类,没有main
测试类:有main
封装:如何正确设计对象的属性和方法
原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
如:人画圆 封装在圆的类中 人关门: 门的方法(门的行为:关着还是开着)
是一个权限修饰符
可以修饰成员
被private修饰的成员只能在本类中才能访问
setXXX(参数):用于给成员变量赋值
getXXX():用于获取成员变量的值
当有成员变量和局部变量重名时,会触发就近原则
this的作用:区别成员变量和局部变量
this的本质:代表方法调用者的地址值
在创建对象的时候给成员变量进行赋值的
方法名与类名相同,大小写也要一致
没有返回值类型,连void都没有
没有具体的返回值(不能由retrun带回结果数据)
空参构造方法:如果没有写任何构造方法,虚拟机会自动加一个空参构造
带参数构造
创建对象的时候由虚拟机调用,,不能手动调用构造方法
每创建一次对象,就会调用一次构造方法
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法
带参构造方法,和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载
无论是否使用,都手动书写无参数构造方法,和带全部参数的构造方法
类名见名知意
成员变量使用private修饰
提供至少两个构造方法
成员方法:每一个成员变量对应set get 方法
将对象存储到数组中
定义一个长度为3的数组,数组存储1~3名学生对象作为初始数据,学生对象的学号,姓名各不相同。 学生的属性:学号,姓名,年龄。 要求1: 再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。 要求2: 添加完毕之后,遍历所有学生信息。 要求3: 通过id删除学生信息 如果存在,则删除,如果不存在,则提示删除失败。 要求4: 删除完毕之后,遍历所有学生信息。 要求5:查询数组id为“heima@e2”的学生,如果存在,则将他的年龄+1岁
API:目前是JDK 中提供的各种功能的java类。这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可
API帮助文档:帮助开发人员更好的使用API和查询API的一个工具。
字符串内容是不会发生改变的,他的对象在创建后不能被更改
创建字符串对象方式:
直接赋值 String s1 = "abc"
new String s2 = new String();
利用字符数组创建字符串
利用字节数组创建字符串
当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在
不存在:创建新的
存在
equals
equalslgnoreCase 比较忽略大小写
str.charAt(i) 得到每一个字符
java String练习-CSDN博客
package com.itheima.apiDemo; import java.util.Scanner; public class StringDemo4 { public static void main(String[] args) { /*金额转换 * 2135转为大写数字 * 分析: * 1.键盘录入一个金额(判断录入是否正确:如金额值是否在0-999999之间,如果不是就继续输入) * 2.将录入的数字转换为中文大写(思路:壹贰叁....存放在一个数组中,遍历金额字符串拿到每一个数字,数字对应的数组索引即为大写数字) * 3.将转换成大写数字 拼接成字符串 * 4.判断该字符串长度,如果小于9 就在其前面拼接‘零’ * 5.将金额所对应的单位存放在数组中,{万 千 百 拾 ....} * 6.遍历字符串,字符串对应的索引即为单位对应的索引,然后将索引对应的单位数组中的值插入到字符串中 * 7.打印输出字符串 * 1234——>零佰零拾零万壹仟贰佰叁拾肆元 * */ // 1.键盘录入一个金额 Scanner sc = new Scanner(System.in); int money; while (true) { System.out.println("请输入一个金额:"); money = sc.nextInt(); if (money >= 0 && money <= 999999999) { break; } else { System.out.println("金额无效,请重新输入"); } } // 定义变量表示钱的大写 String moneyStr = ""; // 2.得到Money中的每一位,再将其转为大写中文 while (true) { // 从右往左获取数据 int ge = money % 10; // 将获取到的数字转换为大写 String captialNum = getCaptialNum(ge); //把转换之后的数字拼接到字符串中 moneyStr = captialNum + moneyStr; System.out.println(moneyStr); // 去掉个位(刚刚获取的数据) money = money / 10; if (money == 0) { break; } } // 3.在前面补0,补齐7位 int count = 7 - moneyStr.length(); for (int i = 0; i < count; i++) { moneyStr = "零" + moneyStr; } System.out.println(moneyStr); // 4.插入单位 // 定义一个数组表示单位 String[] arr = {"佰", "拾", "万", "仟", "佰", "拾", "元" }; //遍历moneystr,依次得到贰壹叁伍 // 然后把arr的单位插入进去 String result = ""; for (int i = 0; i < moneyStr.length(); i++) { char c = moneyStr.charAt(i); /*System.out.print(c); System.out.println(arr[i]);*/ result = result + c + arr[i]; } System.out.println("数字转换为大写中文为:"+result); } // 定义一个方法把数字编程大写的中文 public static String getCaptialNum(int num) { // 定义数组 让数字根大写的中文产生一个对应关系 String[] arr = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; return arr[num]; } }
只有返回值才是截取的小串
/* * 身份证信息查看——》得到出生年月日 性别 * */ String id = "621002202003171234"; // 获取年月日 String year = id.substring(6, 10); String month = id.substring(10, 12); String day = id.substring(12, 14); System.out.println("人物信息为:"); System.out.println("出生年月日:" + year + "年" + month + "月" + day + "天"); // 获取性别 char gender = id.charAt(16); // '0'-------->48 int num = gender-48; if (num%2==0){ System.out.println("性别为:女"); }else{ System.out.println("性别为:男"); }
注意:只有返回值才是替换之后的结果
可以看成一个容器,创建之后里面的内容是可变的
作用:提高字符串的操作效率
使用场景
字符串的拼接
字符串的反转
StringBuilder sb = new StringBuilder(); // 添加元素 sb.append(1); sb.append("abc"); sb.append(true); // 反转 sb.reverse(); // 获取长度 int length = sb.length(); System.out.println(sb); String str = sb.toString(); System.out.println(str);
可以看成一个容器,创建之后里面的内容是可以变换的
作用:提高字符串的操作效率
JDK8 出现的
// 创建一个对象,并制定中间的间隔符号 StringJoiner sj = new StringJoiner("---"); // 添加元素 sj.add("aaa").add("bbb"); System.out.println(sj); // 创建一个对象,并制定开始,结束 中间的间隔符号 StringJoiner sj1 = new StringJoiner(",","[","]"); sj1.add("aa").add("qq").add("ee"); System.out.println(sj1); System.out.println(sj1.length());
扩展底层原理3: 字符串拼接的底层原理
如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串
如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存
扩展底层原理4: stringBuilder提高效率原理图
所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
[字符串综合练习] https://blog.csdn.net/m0_67281369/article/details/134667887?spm=1001.2014.3001.5502
集合长度可变;只能存引用数据类型
// 创建集合的对象 泛型:限定集合中存储数据的类型 /* * 打印对象不是地址值,而是集合中存储的值 用[]包围 * */ ArrayListlist = new ArrayList<>(); list.add("abcd"); list.add("abdd"); list.add("abcc"); boolean res =list.add("abbbb"); System.out.println(res); // 删除 返回被删除的元素 String str = list.remove(0); System.out.println(str); System.out.println(list); // 修改元素 String res1 = list.set(1,"bbbbb"); System.out.println(res1); // 查询元素 list.get(2); // 遍历集合 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
代码ArrayList练习——学生管理系统-CSDN博客
表示静态,可以修饰成员方法、成员变量
特点:
被该类所有对象共享
不属于对象,属于类
随着类的加载而加载,优先于对象存在
调用方式:
类名调用【推荐】
对象调用
特点
多用在测试类和工具类中
JavaBean类(描述一类事物的类)中很少使用
补充—工具类:
类名见名知意
私有化构造方法。目的:不让外界创建对象
方法定义为静态
静态方法中,只能访问静态
非静态方法可以访问所有。
静态方法中没有this关键字
java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系
可以把多个子类重复的代码抽取到父类中,提高代码的复用性
当子类继承父类时,必须要生成构造方法,这样就可以为子类的属性赋值
public class Student extends Person{ @Override public void work() { System.out.println("学生在学习"); } public Student() { } public Student(String name, int age) { super(name, age); } }
当类与类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码
public class 子类 extends 父类{}
java只支持单继承,不支持多继承,但支持多层继承
一个子类只能继承一个父类
子类不能同时集成多个父类
多层继承:子类A继承父类B,父类B可以继承父类C
每一个类都直接或者间接集成于Object
能继承的:成员变量【非私有的可以直接继承使用、私有的成员变量不能直接使用】、非私有的成员方法【虚方法表】
不能继承的:构造方法、私有的成员方法
jps 查看java正在运行的程序地址 hsdb java自带内存分析工具
就近原则:先在局部位置找,本类成员位置找,父类成员位置找,逐级往上
当父类发不能满足子类现在的需求是,需要进行方法重写 @Override重写注写
重写的本质:覆盖了虚方法表中的方法
重写的注意事项:
重写方法的名称、形参列表必须于父类一致
子类重写父类方法时,访问权限子类必须大于等于父类 (暂时了解:空着不写
子类重写父类方法时,返回值类型子类必须小于等于父类
建议: 重写的方法尽量和父类保持一致
只有被添加到虚方法表中的方法才能被重写
父类的构造方法不会被子类继承
子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
子类构造方法第一行语句默认 super()
如果想要调用父类的有参构造,必须手动书写 super(name,age)
this:理解为一个变量,表示当前方法调用者的地址值
super:代表父类存储空间
应用场景:
多态:同类型的对象,表现出不同的形态
表现形式:父类类型 对象名称 = 子类对象;
多态的前提:
有继承/实现关系
有父类引用指向子类对象
有方法的重写
变量调用:编译看左边,运行也看左边
方法调用:编译看左边,运行看右边
在多条形式下,右边对象可以实现解耦合,便于扩展和维护
定义方法是没使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利
不能使用子类的特有功能
如果要使用子类的特有功能 ,必须类型转换
强制转换:可以将对象转换为真正的子类类型,从而调用子类独有功能;转换类型与真实对象类型不一致会报错
转换时用instanceof 关键字进行判断
if (p instanceof Student){ Student stu = (Student) p; stu.study(); } else if (p instanceof Teacher) { Teacher teachsr = (Teacher) p; teachsr.teach(); } // 新特性 Jdk16之后 if (p instanceof Student stu){ stu.study(); } else if (p instanceof Teacher teachsr) { teachsr.teach(); }
包就是文件夹,用来管理各种不同功能的java类
需要导包的情况:
使用同一个包中的类时,不需要导包。
使用java.lang包中的类时,不需要导包。
甚他情况都需要导包
如果同时使用两个包中的同名类,需要用全类名
修饰方法:该方法是最终方法,不能被重写
修饰类:该类是最终类,不能被继承
修饰变量:叫做常量,只能被赋值一次
实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性常量的命名规范:
单个单词:全部大写
多个单词:全部大写,单词之间用下划线隔开
细节:
final修饰的变量是基本类型:那么变量存储的数据值不能发生改变
final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,对内部的可以改变
权限修饰符:是用来控制一个成员能够被访问的范围
可以修饰成员变量,方法,构造方法,内部类
实际开发中:一般只用private和public 【成员变量私有、方法公开】
特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般也私有
写在方法中一段单独的代码块,用完后就回收内存
作用:提前结束变量的生命周期,节约内存【已经淘汰】
写在成员位置中的代码块,
抽取重复的代码块
执行时机:在创建本类对象的时候会先执行构造代码块在执行构造方法【每次创建对象时都会执行】
写法不够灵活 【当有重复代码是,抽取出来写一个单独的方法调用 或者用this()方法调用】【淘汰】
格式:static{}
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景:在类加载的时候,做一些数据初始化的时候使用
抽象方法:将共性的行为 (方法)抽取到父类之后,由于每一个子类执行的内容是不一样所以,在父类中不能确定具体的方法体该方法就可以定义为抽象方法
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类
意义:强制让子类按照某种格式重写
注意事项:
抽象类不能实例化
抽象类中不一定有抽象方法,有抽象方法的了i一定是抽象方法
可以有构造方法【当创建子类对象时,给属性进行赋值的】
抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
public abstract class Person { private String name; private int age; public abstract void work(); } public class Student extends Person{ @Override public void work() { System.out.println("学生在学习"); } }
可以理解为一种规则,对行为的一种抽象
应用:
成员变量
都是常量 默认使用public static final修饰
构造方法 没有
成员方法
只能抽象方法 默认使用public abstract 修饰
只能继承,单继承,不能多继承,但是可以多层继承
可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
继承关系,可以单继承,也可以多继承
多个接口中如果方法有重名,只需要重写一次方法
允许在接口中定义默认方法,需要使用关键字default修饰 【作用:解决接口升级问题】
允许在接口中定义静态方法,需要使用关键字static修饰
默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
public可以省略,default不能省略
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
public可以省略,static不能省略
// 默认方法 public default void show1(){ System.out.println("接口中抽象方法"); } // 静态方法 public static void show2(){ System.out.println("接口中静态方法"); }
私有方法
静态私有方法
// 私有方法 JDK9之后 private void show3(){ System.out.println("接口中普通的私有方法"); } // 静态私有方法 给静态方法服务的 private static void show4(){ System.out.println("接口中的静态私有方法"); }
1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了
2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态
设计模式:(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。【解决各种问题的套路】
适配器设计模式:解决接口与接口实现类之间的矛盾问题
应用:当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以适配器设计模式
书写步骤:
编写中间类XXXAdapter,实现对应的接口对接口中的抽象方法进行空实现
让真正的实现类继承中间类,并只重写需要用的方法
为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰
类的五大成员:属性、方法、构造方法、代码块、内部类
内部类:在一个类的里面,在定义一个类
内部类表示的事务是外部类的一部分,内部类单独出现没有任何意义
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
写在成员位置的,属于外部类的成员
不能用static修饰
获取成员内部类对象方法【查看代码注释】
public class Test { public static void main(String[] args) { Car car = new Car("BM",2,"red"); car.show(); /* 编写成员内部类的注意事项: 1.成员内部类可以被一些修饰符所修饰 2.在成员内部类里面,JDK16之前不能定义静态变量, 获取成员内部类对象方法: 1.外部类编写方法,对外提供内部类对象 2.直接创建 格式: 外部类名。内部类目 对象名 = 外部类对象。内部类对象 Outer.Inner oi = new Outer().new Inner(); */ // 方法一:链式创建 当内部类是public(默认)修饰时 Outer.Inner oi = new Outer().new Inner(); // 方法二 当用private修饰时,在外部类中写一个方法获取内部类,然后调用该方法 Outer o = new Outer(); // 方法一:利用Object对象接收 Object inner1 = o.getInstance(); // 方法二:直接输出 System.out.println(o.getInstance()); } } public class Outer { class Inner{ } private class Inner1{ } public Inner1 getInstance(){ return new Inner1(); } }
练习题:外部成员变量和内部类成员变量重名时,在内部类如何访问?
Outer.this.变量名
静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象
创建静态内部类对象的格式:外部类名。内部类名 对象名 = new 外部类名。内部类名();
调用非静态方法的格式:先创建对象,用对象调用
调用静态方法的格式:外部类名。内部类名。方法名()
// 创建静态内部类对象 Outer.Inner2 oi = new Outer.Inner2(); oi.show1(); // 调用静态方法 Outer.Inner2.show2();
将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
外界是无法直接使用,需要在方法内部创建对象并使用。
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类本质上就是隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置
格式: new 类名或者接口名(){ 重写方法; }; 真正的匿名类是后面的{}中的内容 new 是创建了一个匿名类对象 格式的细节: 包含了继承或实现,方法重写,创建对象 整体就是一个类的子类对象或者接口的实现类对象 使用场景: 当方法的参数是接口或者类时 以接口为例,可以传递这个接口的实现类对象 如果实现类只要使用一次,就可以用匿名内部类简化代码
使用场景:
public class Test { public static void main(String[] args) { method( // 如果Dog类只用一次,在重新定义一个类太麻烦了,此时可以使用匿名内部类 new Animal() { @Override public void eat() { System.out.println("狗吃骨头"); } } ); } public static void method(Animal animal){ animal.eat(); } }
JFrame
JMenuBar JMenu JMenuItem
1,先创建JMenuBar
2,再创建Jmenu
3,再创建]Menultem
4,把]Menultem放到]menu里面
5,把JMenu放到JMenuBar里面
6,最后再把]MenuBar添加到整个Jframe界面中
事件时可以被组件识别的操作
当你对组件干了某件事情之后,就回执行对应的代码
事件源:按钮 图片 窗体...
事件:某些操作:如鼠标淡季,鼠标划入....
绑定监听:当事件源上发生了某个事件,则执行某段代码
键盘监听 KeyListener:按下,释放,
鼠标监听 MousrListener:单击、划入、退出。。。。
动作监听 ActionListener
package com.itheima.test; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Test3 { public static void main(String[] args) { JFrame jFrame = new JFrame(); //设置界面的宽高 jFrame.setSize(603, 680); //设置界面的标题 jFrame.setTitle("事件演示"); //设置界面置顶 jFrame.setAlwaysOnTop(true); //设置界面居中 jFrame.setLocationRelativeTo(null); //设置关闭模式 jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件 jFrame.setLayout(null); //创建一个按钮对象 JButton jtb = new JButton("点我啊"); //设置位置和宽高 jtb.setBounds(0,0,100,50); //给按钮添加动作监听 //jtb:组件对象,表示你要给哪个组件添加事件 //addActionListener:表示我要给组件添加哪个事件监听(动作监听包含鼠标左键点击,空格) //参数:表示事件被触发之后要执行的代码 //jtb.addActionListener(new MyActionListener()); jtb.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("达咩~不要点我哟~"); } }); //把按钮添加到界面当中 jFrame.getContentPane().add(jtb); jFrame.setVisible(true); } }
一定要包含图形化界面
代码要打包起来
游戏用到的图片也要打包起来
把所有代码打包成一个压缩包,jar后缀的压缩包
把jar包转换成exe安装包
把第二步的exe,图片,JDK整合在一起,变成最终的exe安装包
常用方法: abs 获取参数绝对值 ceil 向上取整 向正无穷大方向 floor 向下取整 向负无穷方向 round 四舍五入 max 获取两个整数中较大值 min pow 返回a的b次幂的值 random [0.0,1.0)之间随机数
提高程序效率
package apidemo; public class Mathdemo1 { public static void main(String[] args) { System.out.println(isPrime(889)); } public static boolean isPrime(int number){ int count = 0; for (int i =2; i <=Math.sqrt(number);i++){ count++; if (number%i ==0){ return false; } } System.out.println(count); return true; } }
package apidemo; public class Mathdemo2 { public static void main(String[] args) { /* * 自幂数,一个n位自然数等于自身各个数位上数字的n次幂之和 举例1:三位数1^3 + 5^3 +3^3=153 1^4+6^4+3^4+4^3=1634 举例2:四位数 如果自幂数是一位数,也叫做: 独身数 三位自幂数:水仙花数 四位自幂数:四叶玫瑰数 * */ // 1.统计有多少个水仙花数 100-999 // 循环得到每一个三位数 int count = 0; for (int i = 100; i < 999; i++) { // 分别得到个位 十位 百位 数字 int ge = i % 10; int shi = i / 10 % 10; int bai = i / 100 % 10; // 判断 每一位的三次方之和 跟本身进行比较 double sum = Math.pow(ge,3)+Math.pow(bai,3)+Math.pow(shi,3); if (sum == i){ System.out.println(i+"为水仙花数"); count++; } } System.out.println("水仙花的个数为:"+count); } }
计算机中时间原点:1970.1.1 0.0.0 我国在东八区,有八小时时差1970.1.1 8.0.0
int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int[] arr2 = new int[10]; System.arraycopy(arr1, 0, arr2, 0, 10); for (int i = 0; i < arr2.length; i++) { System.out.print(arr2[i] + ","); } // 方法的形参:状态码 // 0 表示当前虚拟机是正常停止 // 非0: 表示当前虚拟机异常停止 System.exit(0); // 可以用于获取程序运行时间 start- end 获取当前时间的毫秒值 long l = System.currentTimeMillis();
需要获取Runtime对象
// 获取Runtime对象 Runtime runtime = Runtime.getRuntime(); // 获取CPU线程数 System.out.println(Runtime.getRuntime().availableProcessors()); // 总内存大小 单位字节 System.out.println(Runtime.getRuntime().maxMemory()/1024/1024); // 得到单位为MB //7.运行cmd命令 //shutdown :关机//加上参数才能执行 //-s : 默认在1分钟之后关机//-s -t 指定时间 :指定关机时间 // -a : 取消关机操作 //-r:关机并重启 Runtime.getRuntime().exec("shutdown -a");
tostring()
equals(object obj)
clone() 默认为浅克隆
对象克隆:把A对象 的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
Object中的clone是浅克隆
在对象类中重写clone方法
让JavaBean类实现Cloneable接口
创建原对象并调用clone就可以了
User u1 = new User("张三",12); User u2 = (User)u1.clone()
浅克隆:(浅拷贝)不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
深克隆:(深拷贝)基本数据类型拷贝过来 字符串复用 引用数据类型会重新创建新的
// 重写Object克隆方法 浅克隆——》深克隆 @Override protected Object clone() throws CloneNotSupportedException { // 获取克隆对象中的数组 int[] data = this.data; // 创建新的数组 int[] newDate = new int[data.length]; // 拷贝数组中的数据 for (int i = 0; i < data.length; i++) { newDate[i] = data[i]; } // 调用父类中的方法克隆对象 Student stu = (Student) super.clone(); // 因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值 s.data = newDate; return s; //return super.clone(); // 默认是浅克隆 } // 实际中 利用第三方工具包: gson.jar 步骤: 1.当前项目中创建lib包 2.将.jar包放入lib文件夹下 3.右击 存放在library中 代码编写: Gson gson = new Gson(); // 把对象变为一个字符串 String s= gson.toJson(stu) // 在把字符串变回对象就可以了 gson.fromJson(s,stu.class); // 打印对象 System.out.print(stu)
day21
基本查找
前提:数组中的数据必须是有序的
核心:每次排除一半的查找范围
作用:提高查找效率
mid = (min + max )/2