Java 是1995年, 在Sun公司, 由詹姆斯 高斯林主导研发
詹姆斯高斯林被誉为Java之父
由于Sun的管理不善, 被Oracle收购
今后下载Java相关的资源, 就要到 www.oracle.com 进行下载
Java SE : Java语言的标准版, 可以用于桌面应用的开发
目的 : 为了今后要从事的JavaEE开发, 打基础
Java ME : 不学了
Java EE : 可以用于web方向的网站开发
网页 : 用于数据展示
网站 : 网页 + 后台服务器
项目 :
1. 传统项目
XXX人员管理系统 -> 黑马程序员订制的项目 -> 用户并发访问量不大
XXXOA办公系统
2. 互联网项目
淘宝
京东
...
平台 : 这里的平台指的是操作系统
Windows
MacOS
Linux
跨平台 : Java程序可以移植到任意操作系统中运行
原理 : 在不同的操作系统中, 安装一个与之对应版本的 JVM 虚拟机即可
注意 : 允许跨平台的是 Java 程序, 不是JVM虚拟机
04-JDK-JRE-JVM
JVM : Java 虚拟机, 运行Java程序的平台 (载体)
JRE : Java 运行时环境 , 内部包含了 JVM 虚拟机, 还有核心类库
核心类库 : Java已经写好的代码, 我们自己写代码的时候, 要用到这里面的东西.
JDK : 提供给程序员使用的开发工具, 内部包含了 JRE, 还有开发工具
javac.exe 编译工具
java.exe 运行工具
关系 : 包含关系
JDK -> JRE -> JVM
需要了解的JDK版本
JDK5 : 里程碑性质的版本
JDK8 : 国内市场用的最多的版本
JDK11 : 国外市场用的最多的版本
JDK17 : 课程中使用的版本
LTS : 如果JDK带有LTS的标识, 表示是长期维护版本
05-HelloWorld程序
Java程序开发的三个步骤
编写代码
扩展 : 了解java 文件名.java
JDK12版本开始, 允许测试性质的运行
ctrl + shift + K : 笔记软件的快捷键
新建一个.java文件 (源文件) 将代码写到源文件中
public class HelloWorld {
public static void main(String[] args){
System.out.println("HelloWorld");
}
}
编译代码
运行代码
高版本的 JDK 在安装完毕后, 会有一份默认的配置
基础班使用没问题
就业班使用的时候, 就会出现问题
解决 : 删除默认配置, 改进为 JAVA_HOME 的配置方式
JAVA_HOME的配置方式 :
详情参见文档
详情参见文档
介绍 : 在程序的指定位置, 添加的一些说明性信息
简单记 : 对代码的一种解释
注释的分类 :// 注释信息
单行注释
多行注释
注意事项 :
被注释掉的内容, 不会参与程序的编译和运行
IDEA工具, 对于注释有特殊支持// TODO: 描述一些待完成的任务
使用注释对HelloWorld代码做解释
/*
注意信息
*/
/** 注意信息 */
文档注释 : 后期会使用文档注释, 配合工具, 制作API帮助文档
// 通过class关键字创建了一个类, 类名叫做HelloWorld // public 起到限制作用, 限制文件名和类名称保持一致 public class HelloWorld { /* main方法(主方法) 程序执行时的入口 如果没有编写主方法, 程序将无法运行 */ public static void main(String[] args){ // 打印语句 (输出语句) 可以打印 () 中所包裹的内容 System.out.println("HelloWorld"); } }
介绍 : 被 Java 赋予了特定涵义的英文单词
注意 : 关键字已经被Java赋予了特定的涵义, 我们就不允许再使用了
今天认识的关键字 : class : 定义类 public : 起到限制作用, 限制文件名和类名称保持一致 (暂时理解) true : 布尔类型数据(真) false : 布尔类型数据(假) int : 整数的数据类型
目标 : 学习 Java 中有哪些数据我们可以使用
1. 字符串 : 被双引号所包裹的数据 2. 整数 : 所有整数 3. 小数 : 所有小数 4. 字符 : 被单引号所包裹的数据, 内部只能存放单个字符 5. 布尔 : true, false - 单独打印没有意义, 为了配合day02要学习的运算符, 一起使用 - System.out.println(10 > 20); // false 6. 空 : null - 不允许做打印 - day04讲解到引用数据类型的时候, 详细介绍public class ConstantTest { /* 需求: 将自己的个人信息打印在控制台 (姓名, 年龄, 性别, 身高, 婚姻状况) 姓名: 字符串 年龄: 整数 性别: 字符 身高: 小数 婚姻状况: 布尔 */ public static void main(String[] args) { System.out.println("郝以绅"); System.out.println(18); System.out.println('男'); System.out.println(180.1); System.out.println(false); } }
介绍 : 内存中的存储空间, 空间中记录着经常发生改变的数据
变量的定义格式 :
数据类型 变量名 = 数据值; 数据类型: 整数: int
变量的使用 : 根据变量名进行使用
public class VariableDemo1 { /* 变量的介绍 : 变量是内存中的存储空间, 空间中记录着经常发生改变的数据 变量的定义格式 : 数据类型 变量名 = 数据值; 数据类型: 整数: int 使用变量的思路: 根据变量名进行使用 */ public static void main(String[] args) { int salary = 12000; System.out.println(salary); salary = 15000; System.out.println(salary); int age = 18; System.out.println(age); // 步骤1: 定义一个整数类型的变量, 名字叫做 num1, 记录数值100 int num1 = 100; // 步骤2: 定义一个整数类型的变量, 名字叫做 num2, 记录数值200 int num2 = 200; // 步骤3: 定义一个整数类型的变量, 名字叫做 result, 记录数值 num1 + num2 的结果; int result = num1 + num2; // 步骤4: 展示3个变量各自记录的数值. System.out.println(num1); System.out.println(num2); System.out.println(result); } }
简单理解 : 看做为程序的另外一种运行模式, 在这种运行模式下, 程序每一步的执行都是听指挥的
通过查看程序的每一步执行过程, 分析问题, 找到问题, 解决问题
1. 加断点 : 告诉Debug从哪一行代码开始, 听我指挥 2. 选择以Debug方式, 运行程序 3. 点哪里? Step Over : 让程序向下执行一步 4. 看哪里? Debugger : Frames : 可以看到程序中, 有哪些方法正在执行 Variables : 可以看到程序中有哪些变量, 和变量的变化过程 Console : 控制台, 可以看到程序打印出来的数据
变量名不允许重复定义 :
int a = 10; int a = 20; // 编译错误
一条语句可以定义出多个变量, 中间需要使用逗号分隔
int a = 10, b = 20, c = 30;
变量使用之前必须赋值
int num; System.out.println(num); // 编译错误
变量的作用域
变量命名规则:1.可以包含字母,数字,下划线,美元符2.不能以数字开头3.不能是关键字保留字4.true, false, null 字面量常量除外
介绍 : 给类, 方法, 变量...起名字的符号
简单记 : 自己起的名字都是标识符
命名规则:
数字 0 ~ 9
字母 a ~ z A~Z
_ $
不能以数字开头
不能是Java中的关键字
严格区分大小写
命名规范 (江湖规矩) :
小驼峰命名法 : 变量
如果是一个单词, 所有字母小写 age name
如果是多个单词, 从第二个单词开始, 首字母大写 maxAge firstName
大驼峰命名法 : 类
如果是一个单词, 首字母大写 Student
如果是多个单词, 每个单词首字母大写 GoodStudent OperatorDemo ScannerTest
基本数据类型
整数 :
byte 1个字节 -128~127
short 2个字节
int 4个字节
long 8个字节
小数 :
float 4个字节
double 8个字节
字符 :
char 2个字节
布尔 :
boolean 1个字节
使用选择 :
1. 整数类型 : 首先int, 发现int装不下了, 换成long类型, 定义long类型变量需要加入 L 标识
2. 小数类型 : 首选double, 非要用float类型, 需要加入F标识
细节 :
所有整数默认都是 int
System.out.println(10);
所有小数默认都是 double
System.out.println(12.3);
char 类型的取值范围是 0 ~ 65535
在计算机中存储 'a' ---> 字节 ---> 二进制 ---> 01100001 ---> 97
结论: 字符在底层都有一份数值的表示形式
char c = 97;
System.out.println(c); // a
引用数据类型
字符串 : String
package com.itheima.test;
public class DataTypeTest1 {
/*
需求: 请将自己的个人信息, 定义出变量, 并展示在控制台
(姓名, 年龄, 身高, 性别, 婚姻状况)
姓名 : 字符串 --> String
年龄 : 整数 --> int
身高 : 小数 --> double
性别 : 字符 --> char
婚姻状况 : 布尔 --> boolean
*/
public static void main(String[] args) {
// 数据类型 变量名 = 数据值;
String name = "张三";
int age = 23;
double height = 180.1;
char gender = '男';
boolean flag = false;
System.out.println(name);
System.out.println(age);
System.out.println(height);
System.out.println(gender);
System.out.println(flag);
}
}
三个步骤
找符咒
召唤精灵
指挥精灵干活
1. 找符咒
代码: import java.util.Scanner;
位置: 必须写在class的上面
2. 召唤精灵
代码: Scanner sc = new Scanner(System.in);
涵义: 将符咒中的精灵召唤出来
位置: main方法里面
3. 指挥精灵干活
代码:
int age = sc.nextInt(); 从键盘录入整数
String name = sc.next(); 从键盘录入字符串
------------------------------------------------------
double height = sc.nextDouble(); 从键盘接收小数
boolean flag = sc.nextBoolean(); 从键盘接收布尔类型
分类
+
-
*
--------------------------------------
/ : 整数相除, 结果只能得到整数, 如果想要带有小数的结果,需要有小数参与运算
% : 取模, 得到的是除法之后, 剩下的余数
package com.itheima.test;
import java.util.Scanner;
public class OperatorTest1 {
/*
需求: 键盘录入一个三位数, 将其拆分出个位, 十位, 百位, 打印在控制台
个位: 数值 % 10;
十位: 数值 / 10 % 10;
百位: 数值 / 10 / 10 % 10;
千位: 数值 / 10 / 10 / 10 % 10;
万位: 数值 / 10 / 10 / 10 / 10 % 10;
...
简化算法: 针对于数值的最高位, 可以做简化
123 / 100 ---> 1
4567 / 1000 ---> 4
45678 / 10000 ---> 4
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数: ");
int num = sc.nextInt();
int ge = num % 10;
int shi = num / 10 % 10;
int bai = num / 100;
System.out.println("整数" + num + "的个位为:" + ge);
System.out.println("整数" + num + "的十位为:" + shi);
System.out.println("整数" + num + "的百位为:" + bai);
}
}
当 + 号操作过程中, 遇到了双引号字符串, + 号就是字符串连接符, 而不是算数运算了
System.out.println("itheima" + 666); // itheima666
需求: 定义两个变量, 记录3和4, 要求控制台打印的结果是 3 + 4 = 7
int a = 3;
int b = 4;
System.out.println(a + "+" + b + "=" + (a + b));
符号 : ++ , --
++ : 让变量自身的值 +1
-- : 让变量自身的值 -1
使用
1. 单独使用 (推荐)
int a = 10;
a++;
++a;
++在前, 在后没有任何区别.
2. 参与运算使用 (面试喜欢问)
++在前 : 先自增, 再操作
int a = 10;
int b = ++a; // a = 11, b = 11
System.out.println(a); // 11
System.out.println(b); // 11
++在后 : 先操作, 再自增
int a = 10;
int b = a++; // b = 10, a = 11
System.out.println(a); // 11
System.out.println(b); // 10
package com.itheima.test;
public class OperatorTest2 {
/*
不用自己写, 看程序说结果
*/
public static void main(String[] args) {
int a = 10;
int b = ++a;
int c = b++;
System.out.println("a=" + a);
System.out.println("b=" + b);
System.out.println("c=" + c);
System.out.println("------------------------");
int x = 3;
int y = (++x) + (x++) + (x * 10);
System.out.println("x=" + x);
System.out.println("y=" + y);
}
}
注意事项 :
自增自减运算符, 只能操作变量, 不能操作常量
基本赋值运算符
= : 将符号右边的数据, 赋值给左侧的变量
int a = 10;
扩展赋值运算符
+= : 将符号左右两边的数据, 做加法运算, 将结果赋值给左边
int a = 10;
a += 20;
System.out.pritnln(a); // 30
-= :
*= :
/= :
%= :
注意事项 : 扩展赋值运算符, 自带强转效果
double a = 12.3;
int b = 10;
b += a;
System.out.println(b); // 22
小名 : 比较运算符
>
<
>=
<=
==
!=
结论 : 让数据之间作比较, 返回true, false的结果
注意 : 不要把 = 号误写成 ==
代码层面 : 连接boolean类型的表达式或者是值
理解层面 : 整合多个条件, 为一段整体的逻辑
if(score >= 90 && score <= 100){
}
分类 :
&(与) : 并且, 遇false则false
|(或) : 或者, 遇true则true
!(非) : 取反
^(异或) : 相同为false, 不同为true
& : 没有短路效果, 无论符号左边是true,false, 右边都要继续执行
&& : 具有短路效果, 当符号左边为false的时候, 右边就不执行了
如果左边为true, 右边要继续执行
| : 没有短路效果, 无论符号左边是true,false, 右边都要继续执行
|| : 具有短路效果, 当符号左边为true的时候, 右边不执行了
如果左边为false, 右边要继续执行
结论: 今后常用的逻辑运算符
&& || !
三目运算符
效果 : 根据一个判断条件, 从两个数据值, 二者选其一
格式 : 判断条件 ? 值1 : 值2;
1. 执行判断条件, 看其返回结果是true, false
2. true : 值1就是最终结果
3. false : 值2就是最终结果
-------------------------------------------------------
int a = 10;
int b = 20;
int max = a > b ? a : b;
package com.itheima.test;
import java.util.Scanner;
public class OperatorTest3 {
/*
需求: 键盘录入3个整数, 求出最大值, 最小值, 中间值
按照从小到大的顺序, 依次打印
中间值 : num1 + num2 + num3 - max - min;
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个整数 :");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
// 1. 求三个整数的最大值
int tempMax = num1 > num2 ? num1 : num2;
int max = tempMax > num3 ? tempMax : num3;
// 2. 求三个整数的最小值
int tempMin = num1 < num2 ? num1 : num2;
int min = tempMin < num3 ? tempMin : num3;
// 3. 求中间值
int mid = num1 + num2 + num3 - max - min;
System.out.println("最小值为:" + min);
System.out.println("中间值为:" + mid);
System.out.println("最大值为:" + max);
}
}
熟练掌握 () 的使用
常识概念 : && 的优先级是 大于 ||
介绍 : 通过一些语句, 来控制程序的执行流程
分类 :
顺序结构
Java 程序默认的执行流程, 没有特定的语法
分支结构
if
switch
循环结构
for
while
do...while
格式1 :
if (判断条件) {
语句体;
}
执行流程 :
1. 执行判断条件, 看其返回结果是true,false
2. true : 执行 {} 中的语句体
3. false : 不执行 {} 中的语句体
注意事项 :
1. if语句 () 和 {} 之间不要写分号
2. if语句 {} 中, 如果只有一条语句, {} 可以省略不写, 不建议省略
3. if语句 () 中, 无论简单还是复杂, 只要是boolean类型的数据, 就符合语法要求
格式2 :
if (判断条件) {
语句体1;
} else {
语句体2;
}
执行流程:
1. 执行判断条件, 看其返回结果是true, false
2. true : 执行语句体1
3. false : 执行语句体2
public class IfTest1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的密码:");
int password = sc.nextInt();
if (password == 111111) {
System.out.println("密码正确");
} else {
System.out.println("密码错误");
}
}
}
格式3 :
if (判断条件1) {
语句体1;
} else if(判断条件2) {
语句体2;
} else if(判断条件3) {
语句体3;
}
...
else {
语句体n+1;
}
执行流程:
1. 执行判断条件1, 看其返回结果是true, false
true : 执行语句体1, 然后结束掉整个的if语句
false : 执行第二步
2. 执行判断条件2, 看其返回结果是true, false
true : 执行语句体2, 然后结束掉整个的if语句
false : ...
3. 如果所有的判断条件都不成立, 将会执行最后的else
package com.itheima.test;
import java.util.Scanner;
public class IfTest2 {
/*
需求:键盘录入考试成绩,根据成绩所在的区间,程序打印出不同的奖励机制
95 ~ 100 : 自行车一辆
90 ~ 94 : 游乐场玩一次
80 ~ 89 : 变形金刚一个
80 以下 : 挨揍
健壮性判断 : 考虑到一些边界值
*/
public static void main(String[] args) {
// 1. 键盘录入学生成绩
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
// 2. 加入if判断, 看成绩在哪一段范围
if (score < 0 || score > 100) {
System.out.println("您的成绩输入有误!");
} else if (score >= 95 && score <= 100) {
System.out.println("自行车一辆");
} else if (score >= 90 && score <= 94) {
System.out.println("游乐场玩一次");
} else if (score >= 80 && score <= 89) {
System.out.println("变形金刚一个");
} else {
System.out.println("挨揍");
}
}
}
package com.itheima.test;
import java.util.Scanner;
public class IfTest3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
if (score >= 0 && score <= 100) {
// 成绩是正确的
// 代码进入到这个大括号, 说明成绩肯定是0~100之间, 只需要关心, 给什么奖励即可
if (score >= 95 && score <= 100) {
System.out.println("自行车一辆");
} else if (score >= 90 && score <= 94) {
System.out.println("游乐场玩一次");
} else if (score >= 80 && score <= 89) {
System.out.println("变形金刚一个");
} else {
System.out.println("挨揍");
}
} else {
System.out.println("您的成绩输入有误, 请检查是否是0~100分之间");
}
}
}
格式 :
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
执行流程 :
拿着 () 中将要匹配的值, 跟case给出的选项, 逐个进行匹配, 匹配成功, 就执行对应的语句体
随后由break, 结束整个switch语句
如果给出的所有case, 都匹配失败, 将会执行最后 default
注意事项 :
1. case后面的值只能是常量, 不能是变量
2. case后面的值不允许重复
3. switch语句 () 中可以接收的类型 :
A.基本数据类型 : byte short char int
B.引用数据类型 :
JDK5开始, 可以写枚举
JDK7可以, 可以写String字符串
4. 如果省略了break语句, 将会开启case穿透现象
package com.itheima.mswitch;
import java.util.Scanner;
public class SwitchDemo2 {
/*
需求: 键盘录入数值 1~5 , 程序输出工作日
6~7 , 程序输出休息日
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
int week = sc.nextInt();
switch (week) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日");
break;
case 6:
case 7:
System.out.println("休息日");
break;
default:
System.out.println("您的输入有误!");
break;
}
}
}
package com.itheima.mswitch;
import java.util.Scanner;
public class SwitchDemo2 {
/*
JDK14版本开始, case后面允许编写多个值, 中间需要使用逗号分隔
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
int week = sc.nextInt();
switch (week) {
case 1, 2, 3, 4, 5:
System.out.println("工作日");
break;
case 6, 7:
System.out.println("休息日");
break;
default:
System.out.println("您的输入有误!");
break;
}
}
}
if : 适用于范围性的判断
switch : 适用于固定值的匹配
目标 : 为什么要学习循环语句 ?
回答 : 需要将一段代码重复的执行很多次, 就可以使用循环语句
for 循环语句格式 :
for(初始化语句; 判断条件; 条件控制语句){
循环体语句;
}
初始化语句 : 定义变量, 使用这个变量来控制循环
判断条件 : 根据这个判断条件, 决定循环是否要继续
循环体语句 : 要重复执行的代码
条件控制语句 : 改变控制循环的那个变量
for 循环的执行流程 :
1. 执行初始化语句, 在整个循环过程中, 只执行一次
2. 执行判断条件, 看其返回结果是true,还是false
false : 循环结束
true : 进入第三步
3. 执行循环体语句
4. 执行条件控制语句
5. 回到2继续
..
for(int i = 1; i <= 3; i++){
System.out.println("HelloWorld");
}
package com.itheima.test;
public class ForTest1 {
/*
需求: 在控制台打印数字 1~3 和 3~1
积累思路:
1. 用于控制循环的变量, 可以在循环中, 作为一份数据, 继续使用的.
2. 循环的条件控制语句, 不要局限的认为只能是++
*/
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
}
System.out.println("----------------");
for (int i = 3; i >= 1; i--) {
System.out.println(i);
}
System.out.println("----------------");
for (int i = 10; i >= 1; i--) {
System.out.println("干饭倒计时:" + i + "秒");
}
System.out.println("终于等到了饭点, 干饭人干饭时间!");
}
}
package com.itheima.test;
public class ForTest2 {
/*
需求:求1-100之间的偶数和,并把求和结果在控制台输出
分析:
定义求和变量 sum,准备记录累加的结果
使用 for 循环,分别获取数据 1 – 100
循环使用 if 语句,筛选出偶数数据
将每一个偶数数据,和 sum 变量进行累加
循环结束后,打印求和后的结果
积累思路: 今后需求中, 只要是涉及求和, 就要联想到求和变量
*/
public static void main(String[] args) {
// 1. 定义求和变量 sum,准备记录累加的结果
int sum = 0;
// 2. 使用 for 循环,分别获取数据 1 – 100
for (int i = 1; i <= 100; i++) {
// i : 代表1~100之间的每一个数字
// 3. 循环使用 if 语句,筛选出偶数数据
if (i % 2 == 0) {
// 4. 将每一个偶数数据,和 sum 变量进行累加
sum += i;
}
}
// 5. 循环结束后,打印求和后的结果
System.out.println("1~100之间偶数和为:" + sum);
System.out.println("---------------------");
int result = 0;
for (int i = 2; i <= 100; i += 2) {
result += i;
}
System.out.println("1~100之间偶数和为:" + result);
}
}
package com.itheima.test;
public class ForTest5 {
/*
需求: 在控制台打印出所有的水仙花数, 要求一行, 展示两个水仙花数
153 370
371 407
打印语句的区别 :
System.out.println(); 打印数据后, 有换行效果
System.out.print(); 打印数据后, 没有换行效果
*/
public static void main(String[] args) {
// 定义计数器变量, 准备统计, 已经打印了几个水仙花数
int count = 0;
for (int i = 100; i <= 999; i++) {
int ge = i % 10;
int shi = i / 10 % 10;
int bai = i / 100;
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i) {
System.out.print(i + " ");
// 每打印一个水仙花数, 计数器增长
count++;
// 判断是否增长到了偶数, 是的话, 换行
if(count % 2 == 0){
System.out.println();
}
}
}
}
}
for 循环 () 和 {} 之间不要写分号
for 循环 {} 中定义的变量, 在每一轮循环结束, 都会从内存中释放掉
for 循环 () 中定义的变量, 在整个循环结束后, 从内存中释放
因为马虎造成了无限循环 (死循环)
先看懂内循环, 再看外循环
for(int i = 1; i <= 5; i++){
for(int j = 1; j <= 3; j++){
System.out.println("Java");
}
// 内循环单独拿出来, 可以打印3次java
// 整个内循环, 又被循环了5次, 所以程序执行起来, 是15次Java的打印
}
先将大问题, 拆解为小问题实现
需求 : 在控制台使用 * 打印4行5列的矩形
打印了1行5列的
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
然后改进为循环嵌套
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
-------------------------------------------------
for(int i = 1; i <= 4; i++){
for(int j = 1; j <= 5; j++){
System.out.print("*");
}
System.out.println();
}
package com.itheima.test;
public class ForTest6 {
/*
演示循环嵌套的代码 :
需求1 : 使用 * 在控制台打印4行5列的矩形
*****
*****
*****
*****
需求2 : 使用 * 在控制台打印5行的直角三角形
*
**
***
****
*****
*****
****
***
**
*
*/
public static void main(String[] args) {
// 外循环: 控制行数
for(int i = 1; i <= 5; i++){
// 内循环: 控制列数
for(int j = 1; j <= i; j++){
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------------");
// 外循环: 控制行数
for(int i = 5; i >= 1; i--){
// 内循环: 控制列数
for(int j = 1; j <= i; j++){
System.out.print("*");
}
System.out.println();
}
}
}
package com.itheima.test;
public class ForTest7 {
/*
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
...
1. 打印9行9列的矩形
2. 改进9行的直角三角形
3. 改进为99乘法表
------------------------------------------------------------
*号左侧数据 : 每一行中, 都是从1开始, 逐个+1进行增长 j
*号右侧数据 : 每一行中, 右侧的数据, 都是不变的 i
\t : tab键 (制表符)
*/
public static void main(String[] args) {
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();
}
}
}
格式 :
初始化语句;
while (判断条件) {
循环体语句;
条件控制语句;
}
执行流程 :
1. 执行初始化语句, 在整个循环过程中, 只执行一次
2. 执行判断条件, 看其返回结果是true,还是false
false : 循环结束
true : 进入第三步
3. 执行循环体语句
4. 执行条件控制语句
5. 回到2继续
..
int i = 1;
while(i <= 5){
System.out.println("HelloWorld");
i++; // 写while循环, 不要忘记i++操作
}
格式
初始化语句;
do {
循环体语句;
条件控制语句;
}while(判断条件);
int i = 1;
do {
System.out.println("HelloWorld");
i++;
}while(i <= 5);
特点 : 无论判断条件是否满足, 都至少执行一次循环体.
for, while : 先判断, 后执行
do...while : 先执行, 后判断
重点理解 : for循环和while循环的区别
- 两者本质来讲, 没有区别, for循环能够实现的, while都能实现, 反之也是一样.
break : 结束 (终止) 循环, switch
只能在循环和switch语句中使用
continue : 跳过某一次循环, 继续下一次
只能在循环中使用
两种共同的注意事项 : 语句下面不允许写代码, 因为执行不到, 属于无效的代码
细节 :
如果涉及到了循环的嵌套, break, continue, 默认只能操作到自己所在的那一层
如果想要精准的操作到某一层循环, 可以使用标号技术
package com.itheima.test;
import java.util.Scanner;
public class MenuTest {
/*
积累思路: 今后如果不明确循环次数, 可以选择无限循环, 再设计一个出口, 结束无限循环.
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("欢迎来到学生管理系统");
lo:
while (true) {
System.out.println("请输入您的选择: 1. 添加学生 2. 删除学生 3. 修改学生 4. 查看学生 5. 退出");
int choice = sc.nextInt();
switch (choice) {
case 1:
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 lo;
default:
System.out.println("您的输入有误, 请检查是否是1~5的数字");
break;
}
}
}
}
找符咒
召唤精灵
指挥精灵产生随机数
import java.util.Random;
public class Test {
public static void main(Stirng[] args){
Random r = new Random();
int num1 = r.nextInt(100) + 1; // 1~100之间的随机数
int num2 = r.nextInt(61) + 20; // 20~80之间的随机数
}
}
package com.itheima.test;
import java.util.Random;
import java.util.Scanner;
public class RandomTest {
/*
需求: 实现猜数字小游戏
分析:
1. 指挥Random产生一个1~100之间的随机数
int randomNumber;
2. 创建Scanner键盘录入精灵, 录入用户所猜的数据
int scNumber;
3. 比较
猜大了
猜小了
猜对了
*/
public static void main(String[] args) {
Random r = new Random();
Scanner sc = new Scanner(System.in);
// 1. 指挥Random产生一个1~100之间的随机数
int randomNumber = r.nextInt(100) + 1;
while (true) {
// 2. 指挥Scanner录入用户所猜的数据
System.out.println("请输入:");
int scNumber = sc.nextInt();
// 3. 比较
if (scNumber > randomNumber) {
System.out.println("猜大了");
} else if (scNumber < randomNumber) {
System.out.println("猜小了");
} else {
System.out.println("猜对了!");
break;
}
}
System.out.println("感谢您的使用!");
}
}
介绍 : 数组指的是一种容器, 可以存储同种数据类型的多个值
同种数据类型 : 要结合着隐式转换去考虑
建议 : 尽量保证存储的数据, 是同一种类型.
double[] arr1 = {11.1, 22.2, 33};
System.out.println(arr1[2]); // 33.0
int[] arr = {10, 20, 'a'};
System.out.println(arr[2]); // 97
使用场景 :
发现要操作的数据有多个, 并且这多个数据属于同一组数据, 就可以考虑使用数组容器进行维护.
数据类型[] 数组名;
int[] arr;
数据类型 数组名[];
double arr[];
注意 : 以上这两种定义格式, 定义出来的, 仅仅是数组类型的变量而已
并没有将数组容器真正的创建出来
初始化 : 在内存中, 为数组容器开辟空间, 并将数据存入容器的过程
完整格式 :
数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3...};
int[] arr = new int[]{11,22,33};
int[] arr = new int[3]{11,22,33}; // 编译错误, 语法错误
简化格式 : 推荐
数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3...};
int[] arr = {11,22,33};
细节: 简化格式, 简化的只是书写格式, 在运行的时候, 还是会按照完整格式运行.
细节补充 (了解) :
打印数组名, 会看到数组的内存地址
[I@233ac41
@ : 分隔符
[ : 当前空间是一个数组类型的空间, 几个中括号, 就是几维数组
I : 当前数组的数据类型, 是int类型
233ac41 : 十六进制内存地址
格式 :
数组名[索引];
注意 : 根据这个访问格式, 拿到的是真实的数据
索引介绍 : 又称之为角标, 下标
数组容器中, 空间所对应的编号, 编号从0开始, 逐个+1增长
数组遍历 : 将数组中每一个元素都取出来, 进行使用
介绍 : 在初始化数组的时候, 只需要手动指定长度, 系统就会自动分配默认初始化值.
格式 : 数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
理解: 创建了一个数组容器, 这个数组, 可以存储3个int类型的整数
虽然系统会分配默认初始化值 ---> 0
对于程序员来说, 这些初始化值是没有什么意义的, 所以大家可以将这个动态初始化的数组, 看做为是一个空的数组的容器.
默认初始化值的分类 :
整数 : 0
小数 : 0.0
布尔 : false
字符 : '\u0000' -- Unicode字符 --> 常见的体现是空白字符
引用数据类型 : null
引用数据类型 :
数组
类
接口
静态初始化 : 手动指定元素, 系统会根据元素的个数, 自动计算出长度
int[] arr = {11,22,33};
动态初始化 : 手动指定长度, 系统分配默认值
int[] arr = new int[3];
System.out.println(arr[0]); // 0
静态初始化 : 要操作的数据, 需求中已经明确告知了, 直接静态初始化
需求 : 已知班级学生成绩为 100 90 80 100 20 30
int[] arr = {100,90,80,100,20,30};
动态初始化 : 只知道要存储几个元素, 但是不知道具体数值
数组索引越界异常 :
ArrayIndexOutOfBoundsException : 访问了不存在的索引
空指针异常 :
NullPointerException : 当引用数据类型的变量, 被赋值为 null, 意味着和堆内存的连接被切断了
这时候已经找不到堆内存的的数据了, 还非要让他去访问, 就会出现空指针异常
int[] arr = {11,22,33}; // arr = [I@233ac123
arr = null;
System.out.println(arr[0]); // 引发空指针异常
介绍 : 二维数组也是一种容器, 容器中存储的都是一维数组
简单理解 : 容器的嵌套 (数组中存储数组)
二维数组的使用场景 :
发现要操作的数据有多组, 这多组数据还属于一个整体, 就可以考虑使用二维数组进行存储.
举例:
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
int[] arr = {22,66,44,77,33,88,25,数据...}; // 一维数组的弊端 : 需要人为的做分类了
int[][] data = {
{22, 66, 44},
{77, 33, 88},
{25, 45, 65},
{11, 66, 99}
};
完整格式 :
数据类型[][] 数组名 = new 数据类型[][]{ {一维数组1}, {一维数组2}... };
简化格式 :
数据类型[][] 数组名 = { {一维数组1}, {一维数组2}... };
二维数组的元素访问 :
数组名[m索引][n索引];
m索引 : 指定访问哪一个一维数组
n索引 : 指定访问一维数组中的哪一个元素
System.out.println(data[2][1]); // 45
思路 :
先遍历二维数组, 获取每一个一维数组
继续遍历一维数组, 获取内部的元素
int[][] data = {
{22, 66, 44},
{77, 33, 88},
{25, 45, 65},
{11, 66, 99}
};
for(int i = 0; i < data.length; i++){
// data[i] : 每一个一维数组
for(int j = 0; j < data[i].length; j++){
System.out.println(data[i][j]);
}
}
格式 :
数据类型[][] 数组名 = new 数据类型[m][n];
//能够存储两个一维数组, 每一个一维数组中可以存储3个元素
int[][] arr = new int[2][3];
介绍 : 方法 | 函数 (method) : 一段具有独立功能的代码块, 不调用就不执行
方法的好处 :
提高了代码的可阅读性
将原本挤在一起的臃肿代码, 按照功能进行分类管理
提高了代码的复用性
写好了一个方法之后, 可以对方法进行多次调用
问题 : 方法是否可以提高程序的执行效率 ?
不可以 !
public static 返回值类型 方法名 (参数列表) {
方法体;
return 结果;
}
public static : 修饰符, 目前暂时记忆
返回值类型 : 跟方法返回的结果有关系
方法名 : 见名知意, 小驼峰命名法
参数列表 : 方法运行之前所需要的材料
方法体 : 方法中真正执行的逻辑代码
return :
1). 结束方法
2). 用于将结果返还给调用者
设计方法的使用思路 :
1. 参数
问题: 自己这个方法中, 使用的数据, 是否有灵活性的要求 (有没有不确定性数据)
举例1: 设计一个方法, 在控制台打印10次黑马程序员 (不要)
举例2: 设计一个方法, 能够从三个小数中找出最小值 (要参数)
问题: 要参数的话, 要几个? 要什么类型的?
举例1: 设计一个方法, 能够从三个小数中找出最小值
数量: 3个 类型: double
举例2: 设计一个方法, 对数组进行求和操作(要参数)
数量: 1个 类型: int[]
2. 返回值
步骤1: 正常编写代码逻辑
步骤2: 观察自己这个方法, 是否有结果产生
没有结果 : 返回值类型写void
有结果 : 通过return语句返回, 并修改返回值类型.
带返回值方法的调用 :
1. 单独调用(不推荐)
getMax(10,20);
不推荐的原因: 方法的返回值没有接收, 数据丢失
2. 赋值调用(推荐)
int max = getMax(10,20);
推荐原因: 能够拿到真实的数据, 使用起来比较灵活
3. 输出调用(偶尔用)
System.out.println(getMax(10,20));
场景: 测试代码逻辑是否正确
不带返回值方法的调用 (void) :
只能单独调用!!!
方法不调用就不执行
方法与方法之间是平级关系, 不能嵌套定义
方法的编写顺序和执行顺序无关, 要想梳理执行顺序, 就看调用顺序
方法的返回值类型为void, 表示此方法没有返回值的, 可以省略return语句不写
非要写的话, 只能写成 return;
return语句后面不能写代码, 因为执行不到, 属于无效代码
如果一个方法有明确的返回值, 一定要通过return语句带回结果, 无论什么情况下
public static int getMax(int a, int b) {
if (a > b) {
return a;
} else if (b > a) {
return b;
}
// 编译错误, 编译器认为, 代码中的两个return语句, 都被条件所控制
// 如果条件都不成立, 此方法将没有return可以执行.
}
介绍 : 方法与方法之间的一种关系
目标1 : 能够独立识别出, 方法与方法之间, 是否是正确的重载关系
在同一个类中, 方法名相同, 参数不同, 与返回值无关
参数不同:
1. 个数不同
2. 类型不同
3. 顺序不同
目标2 : 能够理解方法重载带来的好处
- 不需要记忆过多繁琐的方法名字了
- 假设没有方法重载
printInt(10);
printDouble(12.3);
printString("abc");
- 有方法重载
println(10);
println(12.3);
println("abc");
在调用方法的时候, JVM虚拟机会根据实际参数的类型, 自动进行匹配
基本数据类型 : 传递的是数据值
引用数据类型 : 传递的是地址值
面向对象并非是一个技术, 而是一种编程的思想
这种思想可以指导我们以什么思路解决问题, 以什么思路来组织代码
问题 : 为什么要学习这种思想 ?
因为这套思想, 来源于生活, 生活中解决问题, 就是一系列的对象, 在一起打交道, 从而将问题解决.
所以我们希望写代码解决问题的时候, 也能按照生活中的这种思想
这样的话, 编程就会更加贴切于生活, 程序也会更加便于让人理解.
举例1: 解决随机数的问题 ---> Random对象
举例2: 解决键盘录入的问题 ---> Scanner对象
举例3: 封装学生数据 ---> Student对象
面向对象我们学什么 ?
学习自己如何设计对象
学习已有的对象如何使用 (API章节)
万物皆对象
生活中的任何一种事物, 都可以通过代码, 将其描述为对象
前提 : Java中想要创建对象, 必须现有类的存在
类的介绍 :
一组相关属性和行为的集合, 将其理解为是对象的一张设计图
对象的介绍 :
对象是根据类 (设计图), 创建出来的实体
类和对象的关系 :
依赖关系 : 需要根据类, 创建对象
数量关系 : 根据一个类, 可以创建出多个对象
类的组成 :
属性 : 在代码中使用成员变量表示, 成员变量跟之前定义变量的格式一样, 只不过位置发生了改变 (类中方法外)
行为 : 在代码中使用成员方法表示, 成员方法跟之前定义方法的格式一样, 只不过去掉了 static 关键字
类的设计
知道什么设计为属性, 什么设计为行为
- 描述事物的一些[名词], 设计为属性
- 描述事物的一些[动词], 设计为行为
举例1: 我有一个{学生}叫做<张三>, 今年<23岁>, <180的身高>, 平时没什么特殊爱好, 就喜欢(吃饭)和(学习).
举例2: 前阵子我买了一台<白色>的<海尔>{洗衣机}, 花了<1999块钱>, (洗衣服)和(甩干)确实方便.
对象的创建和使用
思路 : 当对象创建完毕后, 调用内部的成员, 都是拿着对象名 . 出来的
创建对象的格式 : 类名 对象名 = new 类名();
Student stu = new Student();
System.out.println(stu); // com.itheima.oop.Student@233ac477
使用对象成员变量的格式 : 对象名.变量名;
stu.name = "张三";
stu.age = 23;
System.out.println(stu.name);
System.out.println(stu.age);
使用对象成员方法的格式 : 对象名.方法名();
stu.eat();
stu.study();
细节补充 :
1. 我们在定义类的时候, 成员变量通常不赋值.
(等对象创建完毕后, 再给成员变量赋值)
2. 成员变量没有赋值, 也可以直接使用, 使用的是默认值
类中位置不同 :
成员变量 : 方法外
局部变量 : 方法内
初始化值不同 :
成员变量 : 有默认初始化值
局部变量 : 没有默认初始化值, 使用之前必须完成赋值
内存位置不同 :
成员变量 : 堆内存
局部变量 : 栈内存
生命周期不同 :
成员变量 : 随着对象的创建而存在, 随着对象的消失而消失
局部变量 : 随着方法的调用而存在, 随着方法的运行结束而消失
作用域 :
都在自己所属的大括号中有效
情况 : 当局部变量和成员变量重名
Java会根据就近原则, 优先使用局部变量
问题 : 非要使用成员变量, 怎么办 ?
回答 : 使用this关键字进行区分
class Student {
int num = 10;
public void show(){
int num = 20;
System.out.println(num); // 20
System.out.println(this.num); // 10
}
}
this可以解决的问题 : 区分局部变量和成员变量的重名问题
this的作用 :
this可以调用自己本类的成员
this.本类成员变量;
this.本类成员方法();
-------------------------------------------------
省略规则 :
this.本类成员方法() : this.可以直接省略
this.本类成员变量 : 如果局部变量和成员变量没有重名, this.可以省略不写
class Student {
int num = 10;
public void show(){
System.out.println(this.num); // 10
this.print();
}
public void print(){
...
}
}
介绍 : 构造方法又名构造器
构建, 创造一个对象要调用的方法
简单记 : 构造方法就是用于创建对象的方法
格式 :
1. 方法名与类名相同, 大小写也要一致
2. 没有返回值类型, 连 void 都没有
3. 没有具体的返回值 (不能通过 return 语句带回结果数据)
public class Student {
public Student(){
System.out.println("我是Student类的空参数构造方法");
}
}
构造方法的执行时机 :
在创建对象的时候, 被调用执行
每创建一次对象, 就会执行一次构造方法
构造方法的作用 :
本质作用 : 用来创建对象
结合执行时机 : 在创建对象的时候, 给成员变量初始化
public class Student {
String name;
int age;
public Student(String name, int age){
this.name = name;
this.age = age;
}
}
Student stu = new Student("张三", 23);
构造方法的注意事项 :
如果一个类中没写构造方法, 系统将会给出一个 [默认的] [无参数的] 构造方法
如果手动编写了构造方法, 系统就不会给出那个默认的无参构造了
建议 : 无参构造, 带参构造, 全部手动给出.
构造方法不允许手动调用
stu.Student(); 错误调用
面向对象有三大特征 :
封装
继承
多态
封装思想介绍 :
隐藏实现细节, 仅对外暴露公共的访问方式
结合插线板理解
封装在代码中常见的体现 :
将属性抽取到类中, 是对数据做了封装
使用封装前 : 维护一个用户信息, 定义了5个变量, 数据过于零散
String id = "001";
String name = "张三";
int age = 23;
String tel = "156****1234";
String address = "北京";
----------------------------------------------------------
使用封装后 : 5个零散的数据, 就被封装到了一个整体的对象中
public class User {
String id;
String name;
int age;
String tel;
String address;
// 假设我写了带参数构造方法
}
User u1 = new User("001","张三",23,"156****1234", "北京");
User u2 = new User("002","李四",23,"156****1244", "北京");
将代码抽取到方法中, 是对代码功能进行了封装
程序员A : 编写了一个遍历打印数组的方法
public void printArray(int[] arr){
...
}
程序员B : 无需关心方法内部实现, 只要知道怎么调用即可.
以上过程, 就是程序员A, 将遍历打印数组这个功能代码, 封装到了printArray方法中.
private : 同一个类中
(defualt) : 同一个类中, 同一个包中
protected : 就业班
public : 任意位置
所有成员变量 private 私有
提供空参\带参构造方法
对于私有的成员变量, 提供对应的setXxx和getXxx方法
package com.itheima.test;
/*
标准 JavaBean :
1. 成员变量全部private私有
2. 提供空参\带参构造方法
3. 提供对应的setXxx和getXxx方法
*/
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.itheima.test;
public class StudentTest {
public static void main(String[] args) {
// 1. 空参构造创建对象, 通过setXxx方法完成赋值
Student stu1 = new Student();
stu1.setName("张三");
stu1.setAge(23);
System.out.println(stu1.getName() + "---" + stu1.getAge());
// 2. 带参构造方法创建对象, 在创建的时候直接赋值
Student stu2 = new Student("李四", 24);
System.out.println(stu2.getName() + "---" + stu2.getAge());
// 重点强调: getXxx方法, 能够得到的是真实的数据, 使用方式, 不要局限在打印语句上
for(int i = 1; i <= stu2.getAge(); i++){
System.out.println("祝福" + stu2.getName() + "生日快乐!");
}
}
}
1. 在索引位置搜索自己要查看的类
问题: 我怎么知道该搜哪一个类?
回答: 常用的类, 在课程中都会讲解到.
2. 看包
目的: 看使用的类, 是否在java.lang包 (核心包)
在 : 不需要编写import导包代码
不在 : 必须编写import导包代码
3. 看该类的介绍
目的: 知道这个类能够解决什么问题.
4. 看该类的构造方法
目的: 能够根据构造方法, 将对象创建出来
5. 看该类的成员方法(方法摘要)
① 方法名
② 参数
③ 返回值
④ 介绍
1. Java程序中, 所有双引号字符串, 都是String这个类的对象
- String类, 多了一种创建对象的方式
2. String字符串, 一旦被创建, 就[不可改变]
- 不可改变: 字符串内容不能改变, 要想做修改, 只能使用新的对象做替换.
String s = "abc";
s = "def";
System.out.println(s); // def
3. 字符串虽然不可改变, 但是其内容可以被共享
- 字符串常量池: 当使用双引号创建字符串对象的时候, 会检查常量池中是否存在该数据
没有 : 创建
有 : 复用
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // true
4. 字符串和字符数组之间允许相互转换
char[] chs = {'a','b','c'}; <-----------> String s = "abc";
字符串数组转换字符串
String s = new String(chs);
字符串拆分为字符数组
char[] chs = s.toCharArray();
1. public String() : 创建一个空白的字符串对象
2. public String(char[] chs) : 根据传入的字符数组, 来创建字符串对象
3. public String(String s) : 根据传入的字符串, 来创建字符串对象
细节: 打印字符串对象, 为什么没有地址值?
- TODO: 就业班 (继承, 方法重写, Object, toString())
- 请先暂时记住, 打印字符串对象名, 直接展示内容, 并非地址值.
想法: 这三种创建方式, 都没有双引号直接创建, 来的方便
String s = "abc";
字符串常量池:
jdk8前:在方法区中
jdk8后:在堆内存中
package com.itheima.test;
public class StringTest1 {
/*
String常见面试题 (看程序, 说结果, 并说明原因)
*/
public static void main(String[] args) {
String s1 = "abc";
String s2 = "a" + "b" + "c";
System.out.println(s1 == s2);
}
private static void method3() {
String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c";
System.out.println(s1 == s3);
}
private static void method2() {
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2);
}
private static void method1() {
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);
}
}
public boolean equals(String anObject) :
字符串之间进行内容的比较, 返回true, false
public boolean equalsIgnoreCase(String anotherString) :
字符串之间进行内容的比较, 返回true, false (不考虑大小写)
public boolean isEmpty():
判断字符串是否为空字符串
public boolean startsWith(String):
是否以指定前缀开头
public boolean endsWith(String):
是否以指定后缀结尾
public char[] toCharArray() :
将此字符串转换为一个新的字符数组
public byte[] getBytes():
返回字符串的字节数组
public char charAt(int index) :
根据索引找字符
public int length() :
返回字符串的长度(字符的个数)
public int indexOf(String):
从左到右获取第一次出现的指定字符的下标位置,-1表示没有该字符串
public int indexOf(String,int):
从指定位置开始,从左到右获取第一次出现的....
public int lastIndexOf(String):
从右到左获取....
public String substring(int beginIndex) :
根据传入的索引, 截取字符串, 截取到字符串的末尾, 返回新的字符串
public String substring(int beginIndex, int endIndex) :
根据传入的开始和结束索引, 截取字符串 (包含头, 不包含尾), 返回新的字符串
public String replace(String target, String replacement) :
参数1: 旧值
参数2: 新值
public String[] split(String regex) :
根据传入的字符串作为规则, 切割当前字符串, 并返回字符串数组.
注意: 指定切割规则的时候, 如果没有按照预想的切割出数据
可以在规则前面, 加入 \\
String.join(String 连接符,String... ):连接字符串
public String concat(String):
字符串拼接
new String(name.getBytes("ISO8859-1"), "UTF-8");
处理乱码
public String toLowerCase():
全转小写
public String toUpperCase():
全转大写
public String trim():
左右去空格
问题 : 为什么要学习StringBuilder ?
回答 : 因为StringBuilder可以大幅度提升字符串的操作效率
场景 : 如果今后涉及到字符串的拼接操作, 拼接次数过于频繁, 请一定要使用StringBuilder
介绍 :
StringBuilder是可变的字符序列
StringBuilder又叫做字符串缓冲区 (容器), 这个容器可以存储任意数据类型
但是数据只要进入这个容器, 全部变成字符串.
public StringBuilder() :
创建一个空白的字符串缓冲区, 其初始容量为16个字符
public StringBuilder(String str) :
创建一个字符串缓冲区 (容器), 容器在被创建出来的时候, 就会带有参数数据.
public StringBuilder append(任意类型) :
向缓冲区中, 添加数据, 返回自己这个对象本身
链式编程: 如果一个方法调用结束, 返回的结果是对象, 就可以继续向下调用方法.
sb.append("红色").append("绿色").append("蓝色");
public StringBuilder reverse() :
将缓冲区中的内容进行反转, 返回自己这个对象本身
public int length() :
返回字符的个数
public String toString() :
将缓冲区中的内容转换为字符串, 并返回
public StringBuilder delete(int from,int end):
删除指定范围字符串,不包含end
public StringBuilder deleteCharAt(index):
删除指定下标的字符串
public StringBuilder insert(int,String):
指定位置插入字符串
1. String ---> StringBuilder
场景: 手里的数据是一个String, 但是我要调用的方法, String没有, StringBuilder有, 转换后再调用 !!
1). 使用StringBuilder的空参构造方法, 创建对象, 调用append方法完成添加
String s = "abc";
StringBuilder sb = new StringBuilder();
sb.append(s);
2). 使用StringBuilder的带参构造方法
String s = "abc";
StringBuilder sb = new StringBuilder(s);
2. StringBuilder ---> String
场景: 手里的数据是一个StringBuilder, 但是我要调用的方法, StringBuilder没有, String有, 转换后再调用 !!
1). 调用toString方法
StringBuilder sb = new StringBuilder();
String s = sb.toString();
集合就是一种容器 ,类似于数组
数组的长度是固定的
集合的长度是可变的
数组可以存储基本数据类型, 也可以存储引用数据类型.
集合只能存储引用数据类型, 如果想要存储基本数据类型, 需要使用对应的包装类
byte Byte
short Short
int Integer ***
long Long
float Float
double Double
char Character ***
boolean Boolean
如果要存储数据的个数, 是经常发生改变的, 推荐使用集合容器.
ArrayList
<> : 泛型, 目前对于泛型的理解, 可以对集合中存储的数据类型进行限制
- 泛型类, 泛型方法, 泛型接口, 泛型通配符, 泛型的上下限定..
public boolean add(元素) :
向集合的尾部添加元素, 返回是否添加成功的状态 (返回一般来说, 都不接收)
public void add(int index, 元素);
在指定的索引位置添加对应的元素 (插队添加)
ArrayList
list.add("abc");
list.add("123");
System.out.println(list);
// [abc, 123]
public boolean add(E e) :
向集合的尾部添加元素, 并返回是否添加成功的状态.
public boolean add(int index, E element) :
可以在指定的索引位置, 添加对应的元素 (插队)
public E remove(int index) :
根据传入的索引, 删除集合中元素, 返回被删除的那个元素.
public boolean remove(Object o) :
根据元素删除, 返回是否删除成功的状态
public E set(int index, E element) : 修改指定索引位置, 为对应的元素.
返回被覆盖掉的元素.
以上方法虽然存在返回值, 但返回的结果对我们来说, 意义不大, 可以不做接收.
public int size() :
返回集合中元素的个数
public E get(int index) :
根据索引, 获取集合中的元素