Java入门
IDEA开发
使用idea开发第一个Java程序的步骤
- 创建工程 new Project(空工程)
- 创建模块 new Module
- 创建包 new Package
- 创建类
public static void main(String[] args) ← main/psvm
System.out.println("Hello World"); ← sout
- 编写代码、并启动
- idea中的java程序是自动编译和执行的,编译后的class文件在工程路径下的out文件夹
idea中设置主题、字体、背景色
- 主题配置:File→Settings→Appearance & Behavior→Appearance→Theme
- 字体配置:File→Settings→Editor→Font→Size/line height
- 背景色设置:File→Settings→Editor→Color Scheme→General→Text→Default text
idea常用快捷键及其它操作
- 快捷键/组合几个键一起按下来完成某件事,可以提高开发效率。
main/psvm、sout、…:快速键入相关代码
Ctrl+D:复制当前行数据到下一行
Ctrl+Y:删除所在行,建议用Ctrl+X
Ctrl + ALT +L:格式化代码
Ctrl + ALT +T:快速编辑选中的代码行作为嵌套代码
ALT + SHIFT + ↑ , ALT + SHIFT +↓:上下移动当前代码
Ctrl + / ,Ctrl + Shift +/:对代码进行注释(单行/多行) - 导入模块:新建Module → copy所需src进入新建的module 或者
copy模块进入工程路径 → Module from Existing Sources
(切记选择黑点文件!!!)
注释:注释是写在程序中对代码进行解释说明的文字,方便自己和其他人查看,以便理解程序的。注释并不影响程序的执行,由javac命令编译后的class文件不包含注释。
单行注释:// 注释内容,只能写一行 ← Ctrl+/
多行注释: /* 注释内容1 2 */ ← Ctrl+Shift+/
文档注释:/** 注释内容 */
文档注释的内容是可以提取到一个程序说明文档中去的
基础语法
字面量
字面量:计算机用来处理数据的,字面量就是告诉程序员数据在程序中的书写格式。
常用数据 | 生活中的写法 | 程序中的写法 | 说明 |
---|---|---|---|
整数 | 666,-88 | 666,-88 | 写法一致 |
小数 | 13.14,-5.21 | 13.14,-5.21 | 写法一致 |
字符 | A,C,我 | ‘A’,‘C’,‘我’ | 程序中必须使用单引号,有且仅能一个字符 |
字符串 | 肚子 | “HelloWorld”,“肚子” | 程序中必须使用双引号,内容可有可无 |
布尔值 | 真、假 | true、false | 只有两个值:true代表真,false代表假 |
空值 | 值是:null | 一个特殊的值,空值 | |
特殊的字符:\n 代表的是换行的意思,\t 代表的一个tab |
变量
- 变量:用来存储一个数据的,本质是内存中的一块区域,装的数据可以被替换。
- 变量的完整定义代码格式:
数据类型 变量名称=数据
- 好处:使用变量记要处理的数据,编写的代码更灵活,管理代码更方便
- 变量要先声明,才能使用
- 什么类型的变量,只能存储什么类型的数据
- 变量存在访问范围,同一个范围内,多个变量的名字不能一样
- 变量定义时可以不给赋初始值; 但是在使用时,变量里必须有值
变量详解
- 计算机中表示数据的最小单元: 一个字节(byte,简称B,是使用8个二进制位组成的)
- 字节中的每个二进制位就称为位(bit,简称b),1B=8b
ASCII码表
字符’A’对应的数字是65
字符’a’对应的数字是97
字符’0’对应的数字是48
关键字和标识符
- 关键字就是Java自己要用到的词,并且有特殊含义的一些词
- 我们就不能用来为做为: 类名、变量名,否则会报错!
- 标识符:就是名字,我们写程序时会起一些名字,如类名、变量名等等都是标识符
- 标识符的基本组成: 由数字、字母、下划线和美元符($)等组成
- 标识符的强制要求: 不能以数字开头、不能用关键字做为名字、且是区分大小写的
- 标识符的建议规范
变量名称: 满足标识符规则,同时建议用英文、有意义、首字母小写,满足“驼峰模式”,例如:int studyNumber =59;
类名称: 满足标识符规则,建议全英文、有意义、首字母大写,满足“驼峰模式”,例如:HelloWorld,Student
Debug工具
Debug工具:IDEA自带的断点调试工具,可以控制代码从断点开始一行一行的执行,然后详细观看程序执行的情况
Java语法
数据类型
基本数据类型:4大类8大种
- 随便写一个整型字面量默认是int类型的,424242244444虽然没有超过long的范围,但是超过了本身int类型的范围,而如果希望随便写一个整型字面量默认是long类型的,需要在后面加上L
long lg = 424242244444L; // 默认是int类型,加上L/l就是long类型的数据了
- 随便写小数字面量,默认是double,如果希望小数是float,后面加上F/f
float f = 3.14F; // 默认是double类型,加上F/f就是float类型了
double d = 56.45;
- String 称之为字符串类型,定义的变量可以用于记住一个字符串数据
String name = "张三";
类型转换
- 自动类型转换
类型范围小的变量,可以直接赋值给类型范围大的变量
byte a = 12;
int b = a;
System.out.println(b); // 12
- 表达式的自动类型转换
在表达式中,小范围类型的变量,会自动转换成表达式中较大范围的类型,再参与运算
byte 、short、char → int → long → float → double
注意事项:
表达式的最终结果类型由表达式中的最高类型决定。
在表达式中,byte、short、char是直接转换成int类型参与运算的。
byte i = 10;
short j = 30;
int rs = i + j;
- 强制类型转换
强行将类型范围大的变量、数据赋值给类型范围小的变量。
数据类型 变量2=(数据类型)变量1、数据
int a = 20;
byte b = (byte)a;
注意事项:
强制类型转换可能造成数据(丢失)溢出,浮点型强转成整型,直接丢掉小数部分,保留整数部分返回
int i= 1500;
int i = 1500;
byte j = (byte)i;
System.out.println(j); // -36
double d = 99.5;
int m = (int)d; // 强制类型转换
System.out.println(m); // 99 丢掉小数部分,保留整数部分
运算符
- 基本的算术运算符
“+” 加符号可以做连接符的,与字符串运算的时候是用作连接符的,其结果依然是一个字符串
“abc” + 5 --> “abc5”
能算则算,不能算就在一起。(计算机很聪明!)
int a2 = 5;
System.out.println("abc" + a2); // "abc5"
System.out.println(a2 + 5);// 10
System.out.println("itheima" + a2 + 'a'); // "itheima5a"
System.out.println(a2 + 'a' + "itheima"); // 102itheima
- 自增自减运算符
++、–只能操作变量,不能操作字面量,且如果不是单独使用(如在表达式中、或者同时有其它操作),放在变量前后会存在明显区别
放在变量的前面,先对变量进行+1、-1,再拿变量的值进行运算
int a = 10;
int rs = ++a; (先加再用)
放在变量的后面,先拿变量的值进行运算,再对变量的值进行+1、-1
int b = 10;
int rs = b++; (先用再加)
- 赋值运算符
基本赋值运算符:就是“=”,从右边往左看
int a = 10; // 先看“=”右边,把数据10赋值给左边的变量a存储
扩展赋值运算符:扩展的赋值运算符隐含了强制类型转换
- 关系运算符
判断数据是否满足条件,最终会返回一个判断的结果,这个结果是布尔类型的值: true或者false
注意: 在java中判断是否相等一定是“==”,千万不要把“==”误写成“=”
- 逻辑运算符
把多个条件放在一起运算,最终返回布尔类型的值:true、false
注意: 在java中,“&”、“|”: 无论左边是false还是true,右边都要执行。因此短路与或的运算效率更高!在开发中使用较多 - 三元运算符及运算符优先级
三元运算符格式:条件表达式 ? 值1 : 值2;
执行流程:首先计算关系/条件表达式的值,如果值为true,返回值1,如果为false,返回值2
在表达式中,哪个运算符先执行后执行是要看优先级的,如下表
看看Java是否存在优先级,大家以后需要注意优先级问题
System.out.println(10 > 3|| 10 > 3 && 10 < 3); // true
API概要及案例
- API:Application Programming Interface,应用程序编程接口: Java写好的程序,咱们可以直接调用
- 由Java提供的程序使用说明书
- 使用Java提供的Scanner来完成,步骤如下:
1、导包: import java.util.Scanner;
2、抄代码得到扫描器对象: Scanner sc = new Scanner(System.in)
3、抄代码等待接收用户输入的数据:
int age = sc.nextInt()
String name = sc.next()
Java流程控制
分支结构
- if 分支:根据条件真假来决定执行某段代码
if 使用的几个常见问题
if(条件){ },( )后不能跟“;” 否则{ }中的代码将不受 if 的控制了
如果 if 语句的{ }中只有一行代码的情况,{ }可以省略不写(但是不推荐省略)
一般有如下三种形式
- switch分支:是通过比较值来决定执行哪条分支
switch分支的执行流程:
先执行表达式的值,再拿着这个值去与case后的值进行匹配→
与哪个case后的值匹配为true就执行哪个case块的代码,遇到break就跳出switch分支→
如果全部case后的值与之匹配都是false,则执行default块的代码
使用switch分支的几点注意事项
1、表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、
不支持double、float、long
2、case给出的值不允许重复,且只能是字面量,不能是变量
3、正常使用switch的时候,不要忘记写break,否则会出现穿透现象
多学一招:switch穿透性在有些情况下可以简化代码
当存在多个case分支的代码相同时,可以把相同的代码放到一个case块中,其他的case块都通过穿透性穿透到该case块执行代码即可,这样可以简化代码 - if、switch的比较,以及各自适合什么业务场景?
1、if在功能上远远强大于switch
2、当前条件是区间的时候,应该使用if分支结构。
3、当条件是与一个一个的值比较的时候,switch分支更合适:格式良好、性能较好、代码优雅,性能好在switch可以直接定位分支,而if需要逐一比较
循环结构
- for循环:控制一段代码反复执行很多次,减少代码的重复编写,灵活的控制程序的执行
- while循环:类似for循环,但不清楚具体次数
- while和for有什么区别?什么时候用for,什么时候用while?
功能上是完全一样的,for能解决的while也能解决,反之亦然。
使用规范:知道循环几次——使用for;不知道循环几次——建议使用while。 - do-while循环:先执行 后判断!
- 三种循环的区别(for while do-while)
- 死循环:可以一直执行下去的循环,如果没有干预不会停下来。多用于服务器程序,使得服务器长久保持运行
- 循环嵌套:
跳转关键字
- break:跳出并结束当前所在循环的执行
- continue:用于跳出当前循环的当次执行,直接进入循环的下一次执行
注意事项
break:只能用于结束所在循环,或者结束所在switch分支的执行
continue:只能在循环中进行使用 - 案例:
1、Random的使用:生成随机数
2、猜数字游戏
Java数组
数组的定义和访问
静态初始化数组
- 定义数组的时候直接给数组赋值,而数组属于引用数据类型,存储的是数组在内存中的地址信息
- 数组的访问
如果访问数组时,使用的索引超过了数组最大索引会出什么问题?
执行程序时会出bug,出现一个索引越界的异常提示
- 数组遍历:一个一个数据的访问,实现求和、元素搜索、找最值等功能
动态初始化数组
- 定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组的长度
- 两种数组定义的方法各自适合什么业务场景?
动态初始化:适合开始不确定具体元素值,只知道元素个数的业务场景
静态初始化:适合一开始就知道要存入哪些元素值的业务场景
数组在计算机中的执行原理
- 编译好的java文件进入内存中的JVM虚拟机中为class文件,具体内存分配介绍主要看方法区、栈和堆
而一个数组在计算机中的执行原理则分别加载至这三个区域
简单说说int a = 20; int[] arr = new int[3]
这两行代码的执行原理?
a是变量,直接放在栈中,a变量中存储的数据就是20这个值
new int[3]
是创建一个数组对象,会在堆内存中开辟区域存储3个整数
arr是变量,在栈中,arr中存储的是数组对象在堆内存中的地址值 - 多个变量指向同一个数组
多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
多个数组变量中存储的是==同一个数组对象的地址==
多个变量修改的都是同一个数组对象中的数据
如果某个数组变量中存储的null,代表什么意思?需要注意什么?
代表这个数组变量没有指向数组对象
可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度,会报空指针异常:NullPointerException
Java方法
认识方法
- 方法:方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用
方法的使用注意点:
使用方法的好处:提高了代码的复用性,提高了开发效率;让程序的逻辑更清晰
方法的其他形式及使用问题
方法定义时:需要按照方法解决的实际业务需求,来设计合理的方法形式解决问题
注意事项:
1、如果方法不需要返回数据,返回值类型必须申明成void(无返回值申明),此时方法内部不可以使用return返回数据
2、方法如果不需要接收数据,则不需要定义形参,且调用方法时也不可以传数据给方法了
3、没有参数,且没有返回值类型(void)申明的方法,称为无参数、无返回值的方法,依次类推
方法使用时的常见问题:
1、方法在类中的位置放前放后无所谓,但一个方法不能定义在另一个方法里面。
2、方法的返回值类型写==void(无返回申明)==时,方法内不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。
3、return语句的下面,不能编写代码,属于无效的代码,执行不到这儿。
4、方法不调用就不会执行,调用方法时,传给方法的数据,必须严格匹配方法的参数情况。
5、调用有返回值的方法,有3种方式:1、可以定义变量接收结果,2、或者直接输出调用,3、甚至直接调用;
6、调用无返回值的方法,只有1种方式:只能直接调用
方法的执行原理:在栈内存中先进后出
Java的参数传递机制
基本类型的参数传递
Java的参数传递机制都是:值传递
所谓值传递:指的是在传输实参给方法的形参的时候,传输的是实参变量中存储的值的副本
实参:在方法内部定义的变量
形参:定义方法时“(….)”中所声明的参数
引用类型的参数传递
基本类型和引用类型的参数在传递的时候有什么不同?
都是值传递!
基本类型的参数传输存储的数据值
引用类型的参数传输存储的地址值
方法重载
重载:一个类中,出现多个方法的名称相同,但是它们的形参列表是不同的,那么这些方法就称为方法重载了
- 方法重载的注意事项:
1、一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,其它的都不管(如:修饰符,返回值类型是否一样都无所谓)
2、形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称
- 方法重载的应用:
return关键字在方法中单独使用
不同的是,break关键字是跳出并结束当前所在循环的执行;continue关键字是结束当前所在循环的当次继续,进入下一次执行
Java编程案例
案例目的
- 复习前面学过的编程知识,能够利用所学的知识来解决问题
- 积攒代码量,以训练并提升编程能力、编程思维!
案例1 飞机票优惠价
- 需求:用户购买机票时,机票原价会按照淡季、旺季,头等舱还是经济舱的情况进行相应的优惠,优惠方案如下:5-10月为旺季,头等舱9折,经济舱8.5折;11月到来年4月为淡季,头等舱7折,经济舱6.5折,请开发程序计算出用户当前机票的优惠价。
- 分析:
方法是否需要接收数据?
需要接收机票原价、当前月份、舱位类型
方法是否需要返回数据?
需要返回计算出的机票优惠价
方法内部:先使用if判断月份是旺季还是淡季,然后使用switch分支判断是头等舱还是经济舱 - 遇到需要通过判断数据在哪个区间,来决定执行哪个业务,应该用什么实现?
应该使用if分支结构实现
遇到需要通过判断数据匹配哪个值,来决定执行哪个业务,应该用什么实现?
应该使用switch分支结构实现 - 具体代码实现如下:
public static double calculate(double price, int month, String type) {
// 1.判断月份是淡季还是旺季
if (month >= 5 && month <= 10) {
// 旺季
// 2.判断仓位类型
switch (type) {
case "头等舱":
price *= 0.9;
break;
case "经济舱":
price *= 0.85;
break;
}
} else {
// 淡季
switch (type) {
case "头等舱":
price *= 0.7;
break;
case "经济舱":
price *= 0.65;
break;
}
}
return price;
}
案例2 验证码开发
- 需求:开发一个程序,可以生成指定位数的验证码,每位可以是数字、大小写字母。
- 分析:
方法是否需要接收数据?
需要接收一个整数,控制生成验证码的位数
方法是否需要返回数据?
需要返回生成的验证码
方法内部的业务:使用for循环依次生成每位随机字符,并使用一个String类的变量把每个字符连接起来,最后返回该变量即可 - 核心实现逻辑:
定义一个for循环,循环5次
随机生成0|1|2的数据,依次代表当前要生成的字符是:数字、大写字母、小写字母
把0、1、2交给switch生成对应类型的随机字符
在循环外定义一个String类型的变量用来连接生成的随机字符
循环结束后,返回String类型的变量即是生成的随机验证码 - 具体代码实现如下:
public static String createCode(int n) {
// 1、定义一个for循环用于控制产生多少位随机字符
Random r = new Random();
// 3、定义一个String类型的变量用于记住产生的每位随机字符
String code = "";
for (int i = 1; i <= n; i++) {
// i=1 2 3 4 5
// 2、为每个位置生成一个随机字符:可能是数字、大小写字母。
// 思路:随机一个812之间的数字出来,日代表随机一个数字字符。1、2代表随机大写字母,小写字母。
int type = r.nextInt(3); // 012
switch (type) {
case 0:
// 随机一个数字字符
code += r.nextInt(10); //0-9 code = code +8
break;
case 1:
// 随机一个大写字符A 65 Z 65+25 (0-25)+65
char ch1 = (char) (r.nextInt(26) + 65);
code += ch1;
break;
case 2:
// 随机一个小写字符a 97 z 97+25 (0-25)+97
char ch2 = (char) (r.nextInt(26) + 97);
code += ch2;
break;
}
}
return code;
}
案例3 评委打分
- 需求:在唱歌比赛中,可能有多名评委要给选手打分,分数是
[0-100]
之间的整数。选手最后得分为:去掉最高分、最低分后剩余分数的平均分,请编写程序能够录入多名评委的分数,并算出选手的最终得分。 - 分析:
1、方法是否需要接收数据进行处理?
需要接收评委的人数
2、方法是否需要返回数据?
需要返回计算出的选手最终得分
3、方法内部的业务:定义数组,录入评委的分数存入到数组中去,接着,我们就需要遍历数组中的分数,计算出总分,并找出最高分,最低分、最后按照这些数据算出选手最终得分并返回即可 - 实现步骤:
定义一个动态初始化的数组,用于录入评委打分
提前定义三个变量用来记住数组中的最大值、最小值、总和
遍历数组中的每个数据,依次找出最大值、最小值、总和
遍历结束后,按照计算规则算出选手的最终得分,并返回即可 - 具体代码如下:
public static double getAverageScore(int number) {
// 1、定义一个动态初始化的数组,负责后期存入评委的打分
int[] scores = new int[number]; // 6
// scores = [0, 0, 0, 0, 0, 0] // 2、遍历数组的每个位置,依次录入评委的分数
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
// i=0 1 2 3 4 5
System.out.println("请您录入第" + (i + 1) + "个评委的分数:");
int score = sc.nextInt();
scores[i] = score;
}
//3、从数组中计算出总分,找出最高分,最低分。
int sum = 0; // 求总分用的变量
int max = scores[0]; //求最大值的
int min = scores[0]; //求最小值的。
//遍历数组找出这些数据的.
for (int i = 0; i < scores.length; i++) {
// i= 0 1 2 3 4 5
int score = scores[i];
// 求和
sum += score;
// 求最大值
if (score > max) {
max = score;
}
// 求最小值
if (score < min) {
min = score;
}
}
//4、计算出平均分并返回
return 1.0 * (sum - min - max) / (number - 2);
}
案例4 数字加密
- 需求:
某系统的数字密码是一个四位数,如1983,为了安全,需要加密后再传输,加密规则是:对密码中的每位数,都加5,再对10求余,最后将所有数字顺序反转,得到一串加密后的新数,请设计出满足本需求的加密程序! - 分析
1、方法是否需要接收数据进行处理?
需要接收四位数字密码,进行加密处理
2、方法是否需要返回数据?
需要返回加密后的结果
3、方法内部的业务:将四位数字密码拆分成一个一个的数字,存入到数组中去,遍历数组中的每个数字,按照题目需求进行加密!最后,再把加密后的数字拼接起来返回即可 - 回顾数组元素的反转、交换是如何完成的?
反转数组,就是对数组中的元素,按照前后位置,依次交换数据
如果一个方法里要做的事比较多,我们在开发中一般会怎么做?
一般会把多个事拆成多个方法去完成,也就是独立功能独立成一个方法 - 具体代码如下所示:
public static String encrypt(int number) {
// number = 1983
// 1、把这个密码拆分成一个一个的数字,才可以对其进行加密
int[] numbers = split(number);
// numbers = [1,9,8,3]
// 2、遍历这个数组中的每个数字,对其进行加密处理。
for (int i = 0; i < numbers.length; i++) {
// i = 0 1 2 3
numbers[i] = (numbers[i] + 5) % 10;
}
// numbers = [6,4,3,8]
// 3、对数组反转,把对数组进行反转的操作交给一个独立的方法来
reverse(numbers);
// numbers = [8,3,4,6]
// 4、把这些加密的数字拼接起来做为加密后的结果返回即可。
String data = "";
for (int i = 0; i < numbers.length; i++) {
data += numbers[i];
}
return data;
}
public static void reverse(int[] numbers) {
// 反转数组的
// numbers = [6, 4,3,8]
for (int i = 0, j = numbers.length - 1; i < j; i++, j--) {
//交换1和j位置处的值。
// 1、把后一个位置处的值交给一个临时变量先存起来
int temp = numbers[j];
// 2、把前一个位置处的值赋值给后一个位置处
numbers[j] = numbers[i];
// 3、把后一个位置处原来的值(由临时变量记住着)赋值给前一个位置
numbers[i] = temp;
}
}
public static int[] split(int number) {
// number = 1983
int[] numbers = new int[4];
numbers[0] = number / 1000;
numbers[1] = (number / 100) % 10;
numbers[2] = (number / 10) % 10;
numbers[3] = number % 10;
return numbers;
}
案例5 数组拷贝
- 需求:请把一个整型数组,例如存了数据:11,22,33,拷贝成一个一模一样的新数组出来。
- 分析:
1、方法是否需要接收数据进行处理?
需要接收一个整型数组(原数组)
2、方法是否需要返回数据?
需要返回一个新的、一模一样的整型数组
3、方法内部的业务:创建一个长度一样的整型数组做为新数组,并把原数组的元素对应位置
赋值给新数组,最终返回新数组即可 - 创建出一个与原数组一模一样的数组!而不是赋值到另一个数组
- 具体代码如下所示:
public static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(i == arr.length - 1 ? arr[1] : arr[1] + ",");
System.out.println("]");
}
}
public static int[] copy(int[] arr) {
// arr = [11,22,33]
// 1、创建一个长度一样的整型数组出来。
int[] arr2 = new int[arr.length];
// arr2 = [0,8,0]
// 2、把原数组的元素值对应位置赋值给新数组。
for (int i = 0; i < arr.length ; i++){
// i = 0 1 2
arr2[i] = arr[i];
}
return arr2;
}
案例6 抢红包
- 需求:
一个大V直播时发起了抢红包活动,分别有:9、666、188、520、99999五个红包。请模拟粉丝来抽奖,按照先来先得,随机抽取,抽完即止,注意:一个红包只能被抽一次,先抽或后抽哪一个红包是随机的 - 分析:
1、方法是否需要接收数据进行处理?
需要接收一个数组,里面是5个金额,表示5个红包
2、方法是否需要返回数据?不需要
3、方法内部完成本需求:先把数组里面的5个金额打乱顺序,打乱后的顺序就认为是中奖顺序;接着,写个for循环,执行5次,每次都提示抽奖;每次抽奖,都依次取出数组中的每个位置处的金额作为中奖金额即可 - 打乱奖金的顺序,再依次发给粉丝遍历数组中的每个位置,每遍历到一个位置,都随机一个索引值出来,让当前位置与该索引位置处的数据进行交换
- 具体代码如下所示:
public static void start(int[] moneys) {
// moneys = [9, 666, 188, 520, 99999]
Scanner sc = new Scanner(System.in);
Random r = new Random();
int temp;
// 1、定义一个for循环,控制打乱5次来确定为抽奖顺序
for (int i = 0; i < 5; i++) {
int index = r.nextInt(5);
temp = moneys[index];
moneys[index] = moneys[i];
moneys[i] = temp;
}
for (int i = 0; i < 5; i++) {
// 2、提示粉丝抽奖
System.out.println("请发送弹幕来开始抽奖:");
sc.next(); // 等待用户输入内容,按了回车才往下走
System.out.println("恭喜您抽中了红包:" + moneys[i] + "!");
}
System.out.println("活动结束...");
}
案例7 找素数
- 需求:除了1和它本身以外,不能被其他正整数整除,就叫素数。按要求遍历出指定范围内素数,比如,3、7就是素数,而9、21等等不是素数
- 分析:
1、方法是否需要接收数据进行处理?需要接收101以及200,以便找该区间中的素数
2、方法是否需要返回数据?需要返回找到的素数个数
3、方法内部的实现逻辑:使用for循环来产生如101到200之间的每个数;每拿到一个数,判断该数是否是素数;判断规则是:
从2开始遍历到该数的一半的数据,看是否有数据可以整除它,有则不是素数,没有则是素数;根据判定的结果来决定是否输出这个数据(是素数则输出);最后还需要统计素数的个数并返回 - 定义了flag标记位→ 遍历2到该数的一半的数据去判断是否有整除的数据,有则改变falg标记位的状态→ 最终通过flag的状态判断是否是素数
- 具体代码如下所示:
public static int search(int start, int end) {
int count = 0;
// start = 101 end =200
// 1、定义一个for循环找到101到200之间的每个数据
for (int i = start; i <= end ; i++){
// i =101 102 183... 199 200
//信号位思想
boolean flag = true; // 假设的意思:默认认为当前i记住的数据是素数.
//2、判断当前1记住的这个数据是否是素数。
for (int j = 2; j <= i / 2 ; j++) {
if (i % j == 0) {
// i当前记住的这个数据不是素数了
flag = false;
break;
}
}
// 3、根据判定的结果决定是否输出i当前记住的数据:是素数才输出展示。
if (flag) {
System.out.println(i);
count++;
}
}
return count;
}
案例8/9 乘法表和打印星星
乘法表代码:
public static void main(String[] args) {
// 1、定义一个for循环控制打印多少行
for (int i = 1; i <= 9; i++) {
// i=123456789
// 2、定义一个内部循环控制每行打印多少列。
for (int j = 1; j <= i; j++) {
// i 行 j 列
System.out.print(j + "x" + i + "=" + (j * i) + "\t");
}
System.out.println(); // 换行
}
}
打印星星代码:
public static void main(String[] args) {
// 1、先定义一个循环控制打印多少行
int n = 5;
for (int i = 1; i <= n; i++) {
//2、控制打印多少个空格
for (int j = 1; j <= (n - i); j++) {
System.out.print(" ");
}
//3、控制打印多少个星星
for (int j = 1; j <= (2 * i - 1); j++) {
System.out.print(j % 2 == 0 ? " " : "*");
}
//4、换行
System.out.println();
}
}
案例10 实现双色球
- 双色球业务介绍:投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1-33中选
择;蓝色球号码从1-16中选择 - 分析:
1、用于让用户投注一组号码(前6个是红球,最后1个是蓝球),并返回用户投注的号码,注意规则是6个红球号码的范围是1-33之间,且不能重复;1个蓝球号码的范围在1-16之间。
2、系统随机一组中奖号码(前6个是红球,最后1个是蓝球),并返回这组中奖号码
3、传入两组号码,用来判断用户投注号码的中奖情况,并输出 - 如何去保证用户投注的6个红球号码不重复的?
每次用户投注一个红球号码后,都去调用一个方法来判断这个号码是否已经选择过,如果选择过,让用户重新选号
如何去保证随机的6个中奖的红球号码不重复的?
每次随机一个1-33之间的红球号码后,都去调用一个方法来判断这个号码是否已经出现过,如果出现过,让用户重新选号
如何去统计用户投注的红球的命中数量的?
遍历用户选择的每个红球号码,每遍历一个红球号码时,都去遍历中奖号码数组中的全部红球号码,看当前选的红球号码是否在中奖号码中存在,存在则红球命中数量加1 - 具体代码如下:
public static void main(String[] args) {
// 目标:完成双色球系统的开发。
int[] userNumbers = userSelectNumbers();
System.out.println("您投注的号码:");
printArray(userNumbers);
int[] luckNumbers = createLuckNumbers();
System.out.println("中奖的号码:");
printArray(luckNumbers);
judge(userNumbers, luckNumbers);
}
/** 1、设计一个方法,用于让用户投注一组号码并返回(前6个是红球号码,最后1个是蓝球号码 )*/
public static int[] userSelectNumbers(){
// 2、创建一个整型数组,用于存储用户投注的7个号码(前6个是红球号码,最后1个是蓝球号码 )
int[] numbers = new int[7];
// numbers = [0, 0, 0, 0, 0, 0, 0]
// 0 1 2 3 4 5 6
Scanner sc = new Scanner(System.in);
// 3、遍历前6个位置,让用户依次投注6个红球号码,存入
for (int i = 0; i < numbers.length - 1; i++) {
// i = 0 1 2 3 4 5
while (true) {
// 4、开始让用户为当前位置投注一个红球号码(1-33之间,不能重复)
System.out.println("请您输入第" + (i + 1) + "个红球号码(1-33之间,不能重复):");
int number = sc.nextInt();
// 5、先判断用户输入的红球号码是否在1-33之间
if(number < 1 || number > 33){
System.out.println("对不起,您输入的红球号码不在1-33之间,请确认!");
}else {
// 号码是在1-33之间了,接着还要继续判断这个号码是否重复,不重复才可以使用。
if(exist(numbers, number)){
// number当前这个红球号码是重复了。
System.out.println("对不起,您当前输入的红球号码前面选择过,重复了,请确认!");
}else {
// number记住的这个号码没有重复了,就可以使用了。
numbers[i] = number;
break; // 结束当次投注,结束了当前死循环。
}
}
}
}
// 6、投注最后一个蓝球号码。
while (true) {
System.out.println("请您输入最后1个蓝球号码(1-16):");
int number = sc.nextInt();
if(number < 1 || number > 16){
System.out.println("对不起,您输入的蓝球号码范围不对!");
}else {
numbers[6] = number;
break; // 蓝球号码录入成功,结束死循环
}
}
return numbers;
}
private static boolean exist(int[] numbers, int number) {
// 需求:判断number这个数字是否在numbers数组中存在。
// numbers = [12, 25, 18, 0, 0, 0, 0]
// number = 12 for (int i = 0; i < numbers.length; i++) {
if(numbers[i] == 0){
break;
}
if(numbers[i] == number){
return true;
}
}
return false;
}
public static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(i == arr.length - 1 ? arr[i] : arr[i] + ", ");
}
System.out.println("]");
}
/** 2、设计一个方法:随机一组中奖号码出来(6个红球号码,1个蓝球号码 )*/
public static int[] createLuckNumbers(){
// 1、创建一个整型数组,用于存储这7个号码
int[] numbers = new int[7];
Random r = new Random();
// 2、遍历前6个位置处,依次随机一个红球号码存入(1-33 不重复)
for (int i = 0; i < numbers.length - 1; i++) {
// i = 0 1 2 3 4 5
while (true) {
// 3、为当前这个位置随机一个红球号码出来存入。 1 - 33 ==> -1 ===> (0 , 32) + 1 int number = r.nextInt(33) + 1;
// 4、判断这个号码是否之前出现过(红球号码不能重复)。
if(!exist(numbers, number)){
// number不重复。
numbers[i] = number;
break; // 结束死循环,代表找到了当前这个位置的一个不重复的红球号码了。
}
}
}
// 3、录入一个蓝球号码。 1-16 numbers[6] = r.nextInt(16) + 1;
return numbers;
}
/** 3、设计一个方法,用于判断用户的中奖情况 */
public static void judge(int[] userNumbers,int[] luckNumbers){
// userNumbers = [12, 14, 16, 18, 23, 26, 8]
// luckNumbers = [16, 17, 18, 19, 26, 32, 8]
// 2、分别定义2个变量用于记住红球命中了几个以及蓝球命中了几个
int redCount = 0;
int blueCount = 0;
// 先判断红球命中的数量。
// 遍历用户投注的号码的前6个红球
for (int i = 0; i < userNumbers.length - 1; i++) {
// userNumbers[i]
// 开始遍历中奖号码的前6个红球号码,看用户当前选择的这个号码是否命中了
for (int j = 0; j < luckNumbers.length - 1; j++) {
if(userNumbers[i] == luckNumbers[j]){
redCount++;
break;
}
}
}
// 3、判断蓝球是否命中了
blueCount = userNumbers[6] == luckNumbers[6] ? 1 : 0;
System.out.println("您命中的红球数量是:" + redCount);
System.out.println("您命中的蓝球数量是:" + blueCount);
// 4、判断中奖详情,并输出结果
if(redCount == 6 && blueCount == 1){
System.out.println("恭喜您,中奖1000万,可以开始享受人生了~~~");
}else if(redCount == 6 && blueCount == 0){
System.out.println("恭喜您,中奖500万,可以稍微开始享受人生了~~~");
}else if(redCount == 5 && blueCount == 1){
System.out.println("恭喜您,中奖3000元,可以出去吃顿小龙虾了~");
}else if(redCount == 5 && blueCount == 0 || redCount == 4 && blueCount == 1){
System.out.println("恭喜您,中了小奖:200元~");
}else if(redCount == 4 && blueCount == 0 || redCount == 3 && blueCount == 1){
System.out.println("中了10元~");
}else if( redCount < 3 && blueCount == 1){
System.out.println("中了5元~");
}else {
System.out.println("感谢您对福利事业做出的巨大贡献~~~");
}
}
面向对象编程
快速入门
面向对象编程快速入门,计算机是用来处理数据的。开发一个一个的对象,把数据交给对象,再调用对象的方法来完成对数据的处理!
深入认识面向对象
- 面向对象编程有啥好处?
万物皆对象!
汽车的数据 找汽车对象处理
手机的数据 找手机对象处理
学生的数据 找学生对象处理
这样符合人类思维习惯,编程更简单、更直观 - 程序中的对象如何理解?
- 面向对象如何理解?
总结来说,就是先用class设计出对象/表格,再new出新对象,有类于C语言的结构体
多个对象在计算机中的执行原理
计算机执行代码时,先将class文件加载至方法区,main方法进入栈内存,并加载new出来的s1和s2新对象,同时记录着加载在堆内存的表的首地址,实现多个对象在计算机中的执行
对象在计算机中的执行原理是怎么回事?
Student s1 = new Student();
这是引用类型的变量,因为s1存储的是地址
每次new Student(),就是在堆内存中开辟一块内存区域代表一个学生对象
s1变量里面记住的是学生对象的地址
类和对象的一些注意事项
- 类名建议用英文单词,首字母大写,满足驼峰模式,且要有意义,比如:Student、Car…
- 类中定义的变量也称为成员变量(对象的属性),类中定义的方法也称为成员方法(对象的行为)
- 成员变量本身存在默认值,同学们在定义成员变量时一般来说不需要赋初始值(没有意义)
- 一个代码文件中,可以写多个class类,但只能一个用public修饰,且public修饰的类名必须成为代码文件名
- 对象与对象之间的数据不会相互影响,但多个变量指向同一个对象时就会相互影响了
- 如果某个对象没有一个变量引用它,则该对象无法被操作了,该对象会成为所谓的垃圾对象。Java存在自动垃圾回收机制,会自动清楚掉垃圾对象,程序员不用操心
this关键字
this:this就是一个变量,可以用在方法中,来拿到当前对象
主要用于解决:变量名称冲突问题
在方法中this是被隐含调用了才拿到了当前对象,如下方法区中的
public void printThis(Student this)
中的Student this
即被默认调用了,无需额外添加
构造器
- 构造器的样子:
public class Student {
/** 构造器*/
public Student() {
Student s = new Student();
}
- 构造器的特点:创建对象时,对象会去调用构造器
Student s = new Student();
- 构造器的常见应用场景:创建对象时,同时完成对对象成员变量(属性)
- 构造器的注意事项:
类在设计时,如果不写构造器,Java是会为类自动生成一个无参构造器的
一旦定义了有参数构造器,Java就不会帮我们的类自动生成无参构造器了,此时就建议自己手写一个无参数构造器出来了
封装
- 什么是封装?
就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理这些数据的方法,设计到一个对象中去
- 面向对象的三大特征:封装、继承、多态
- 封装的设计规范是什么样的?
合理隐藏,合理暴露! - 代码层面如何控对象的成员公开或隐藏?
公开成员,可以使用public(公开)进行修饰
隐藏成员,使用private(私有,隐藏)进行修饰
实体类 JavaBean
- 什么是实体类?有啥特点?
成员变量必须私有,且要为他们提供get、set方法;必须有无参数构造器
仅仅只是一个用来保存数据的java类,可以用它创建对象,保存某个事物的数据 - 实体类有啥应用场景?
实体类对应的是软件开发里现在比较流行的开发方式,数据和数据的业务处理相分离
- 快速编辑:在Idea中右键然后Generate可以快速创建Getter and Setter,并选择需要创建get&set的成员变量
成员变量和局部变量的区别
面向对象案例实践
package com.java.object;
import java.util.Scanner;
/**
目标:完成电影信息展示功能; 根据电影id查询该电影详情。
电影数据: 1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看"
2,"出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看"
3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看"
4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看"
*/
public class MovieTest {
public static void main(String[] args) {
// 1、设计一个电影类
// 2、设计一个电影的操作类
// 3、准备 全部电影数据
Movie[] movies = new Movie[4];
movies[0] = new Movie(1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看");
movies[1] = new Movie(2,"出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看");
movies[2] = new Movie(3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看");
movies[3] = new Movie(4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看");
// 4、创建一个电影操作类的对象,接收电影数据,并对其进行业务处理
MovieOperator operator = new MovieOperator(movies);
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("==电影信息系统==");
System.out.println("1、查询全部电影信息");
System.out.println("2、根据id查询某个电影的详细信息展示");
System.out.println("请您输入操作命令:");
int command = sc.nextInt();
switch (command) {
case 1:
// 展示全部电影信息
operator.printAllMovies();
break;
case 2:
// 根据id查询某个电影的详细信息展示
System.out.println("请您输入查询的电影id:");
int id = sc.nextInt();
operator.searchMovieById(id);
break;
default:
System.out.println("您输入的命令有问题~~");
}
}
}
}
package com.java.object;
public class Movie {
private int id;
private String name;
private double price;
private double score;
private String director;
private String actor;
private String info;
public Movie() {
}
public Movie(int id, String name, double price, double score, String director, String actor, String info) {
this.id = id;
this.name = name;
this.price = price;
this.score = score;
this.director = director;
this.actor = actor;
this.info = info;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
package com.java.object;
public class MovieOperator {
private Movie[] movies;
public MovieOperator(Movie[] movies){
this.movies = movies;
}
/** 1、展示系统全部电影信息 movies = [m1, m2, m3, ...]*/
public void printAllMovies(){
System.out.println("-----系统全部电影信息如下:-------");
for (int i = 0; i < movies.length; i++) {
Movie m = movies[i];
System.out.println("编号:" + m.getId());
System.out.println("名称:" + m.getName());
System.out.println("价格:" + m.getPrice());
System.out.println("------------------------");
}
}
/** 2、根据电影的编号查询出该电影的详细信息并展示 */
public void searchMovieById(int id){
for (int i = 0; i < movies.length; i++) {
Movie m = movies[i];
if(m.getId() == id){
System.out.println("该电影详情如下:");
System.out.println("编号:" + m.getId());
System.out.println("名称:" + m.getName());
System.out.println("价格:" + m.getPrice());
System.out.println("得分:" + m.getScore());
System.out.println("导演:" + m.getDirector());
System.out.println("主演:" + m.getActor());
System.out.println("其他信息:" + m.getInfo());
return; // 已经找到了电影信息,没有必要再执行了
}
}
System.out.println("没有该电影信息~");
}
}
API
API介绍、包
- API (全称 Application Programming Interface:应用程序编程接口)
就是别人写好的一些程序,给咱们程序员直接拿去调用即可解决问题的 - 为什么要学别人写好的程序?
不要重复造轮子!
Java已经20多岁了~开发效率高!
Java的深入学习即是面向对象高级语法 → 学习、熟悉一个一个的API
因此我们首先学习包 - 包是分门别类管理程序的地方-package
- 在IDEA中设置自动导包
- 在自己程序中调用其他包下的程序的注意事项
如果当前程序中,要调用自己所在包下的其他程序,可以直接调用。(同一个包下的类,互相可以直接调用)
如果当前程序中,要调用其他包下的程序,则必须在当前程序中导包,才可以访问!导包格式:import 包名.类名;
如果当前程序中,要调用Java提供的程序,也需要先导包才可以使用;但是Java.lang包下的程序是不需要我们导包的,可以直接使用
如果当前程序中,要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问
//1、同一个包下的程序,可以直接访问。
Demo d = new Demo();
d.print();
//2、访问其他包下的程序,必须导包才可以访问。
Demo1 d2 = new Demo1();
d2.print();
// 3、自己的程序中调用Java提供的程序,也需要先导包才可以使用;注意:Java.lang包下的程序是不需要我们导包的,可以直接使用。
Scanner sc = new Scanner(System.in);
String s= "肚子";
Random r = new Random();
//4、访问多个其他包下的程序,这些程序名又一样的情况下,默认只能导入一个程序,另一个程序必须带包名和类名来访问。
Demo2 d3 = new Demo2();
d3.print();
com.itheima.pkg.itcast.Demo2 d4 = new com.itheima.pkg.itcast.Demo2();
d4.print();
String类
- 代表字符串,可以用来创建对象封装字符串数据,并对其进行处理
- String创建对象封装字符串数据的方式
方式一:Java 程序中的所有字符串文字(例如“abc”)都为此类的对象
String name =“肚子”;
String schoolName =“程序员”;
方式二:调用String类的构造器初始化字符串对象
//目标:掌握创建String对象,并封装要处理的字符申的两种方式。
//1、直接双引号得到字符串对象,封装字符串数据
String name = "itheima";
System.out.println(name);
// 2、new String创建字符串对象,并调用构造器初始化字符串
String rs1 = new String();
System.out.println(rs1); //""
String rs2 = new String(original:"itheima");
System.out.println(rs2);
char[] chars = {'a','k'};
String rs3 = new String(chars);
System.out.println(rs3);
byte[] bytes = {97,98,99};
String rs4 =new String(bytes);
System.out.println(rs4);
String的常用方法
- public int length()
获取字符串的长度返回(就是字符个数) - public char charAt(int index)
获取某个索引位置处的字符返回 - public char[] toCharArray():
将当前字符串转换成字符数组返回 - public boolean equals(Object anObject)
判断当前字符串与另一个字符串的内容一样,一样返回true - public boolean equalsIgnoreCase(String anotherString)
判断当前字符串与另一个字符串的内容是否一样(忽略大小写) - public String substring(int beginIndex, int endIndex)
根据开始和结束索引进行截取,得到新的字符串(包前不包后) - public String substring(int beginIndex)
从传入的索引处截取,截取到末尾,得到新的字符串返回 - public String replace(CharSequence target,CharSequence replacement)
使用新值,将字符串中的旧值替换,得到新的字符串 - public boolean contains(CharSequence s)
判断字符串中是否包含了某个字符串 - public boolean startsWith(String prefix)
判断字符串是否以某个字符串内容开头,开头返回true,反之 - public String[] split(String regex)
把字符串按照某个字符串内容分割,并返回字符串数组回来
// 目标:快速熟悉String提供的处理字符串的常用方法。
java.lang.String s = "黑马Java";
// 1、获取字符串的长度
System.out.println(s.length());
// 2、提取字符串中某个索引位置处的字符
char c = s.charAt(1);
System.out.println(c);
// 字符串的遍历
for (int i = 0; i < s.length(); i++) {
// i = 0 1 2 3 4 5
char ch = s.charAt(i);
System.out.println(ch);
}
System.out.println("-------------------");
// 3、把字符串转换成字符数组,再进行遍历
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
// 4、判断字符串内容,内容一样就返回true
java.lang.String s1 = new java.lang.String("黑马");
java.lang.String s2 = new java.lang.String("黑马");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
// 5、忽略大小写比较字符串内容
java.lang.String c1 = "34AeFG";
java.lang.String c2 = "34aEfg";
System.out.println(c1.equals(c2)); // false
System.out.println(c1.equalsIgnoreCase(c2)); // true
// 6、截取字符串内容 (包前不包后的)
java.lang.String s3 = "Java是最好的编程语言之一";
java.lang.String rs = s3.substring(0, 8);
System.out.println(rs);
// 7、从当前索引位置一直截取到字符串的末尾
java.lang.String rs2 = s3.substring(5);
System.out.println(rs2);
// 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们
java.lang.String info = "这个电影简直是个垃圾,垃圾电影!!";
java.lang.String rs3 = info.replace("垃圾", "**");
System.out.println(rs3);
// 9、判断字符串中是否包含某个关键字
java.lang.String info2 = "Java是最好的编程语言之一,我爱Java,Java不爱我!";
System.out.println(info2.contains("Java"));
System.out.println(info2.contains("java"));
System.out.println(info2.contains("Java2"));
// 10、判断字符串是否以某个字符串开头。
java.lang.String rs4 = "张三丰";
System.out.println(rs4.startsWith("张"));
System.out.println(rs4.startsWith("张三"));
System.out.println(rs4.startsWith("张三2"));
// 11、把字符串按照某个指定内容分割成多个字符串,放到一个字符串数组中返回给我们
java.lang.String rs5 = "张无忌,周芷若,殷素素,赵敏";
java.lang.String[] names = rs5.split(",");
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
String的注意事项
- String是不可变字符串对象
- 只要是以“…”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;
- 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
- 案例理解:
String的应用案例1 完成用户登录
- 需求:系统正确的登录名和密码是:itheima/123456,请在控制台开发一个登录界面,接收用户输入的登录名和密码,判断用户是否登录成功,登录成功后展示:“欢迎进入系统!”,即可停止程序(注意:要求最多给用户三次登录机会)
- 步骤:
1、开发登录界面,提示用户通过键盘输入登录名和密码。
2、设计一个登录方法,对用户的登录名和密码进行正确性认证。
3、根据登录方法返回的认证结果,判断用户是否登录成功。
4、使用循环控制登录界面最多显示3次。 - 注意事项:
字符串的比较使用比较好吗?为什么?什么时候使用双等于号?
不好,对于字符串对象的比较,双等于号比较的是地址,容易出业务bug
基本数据类型的变量或者值应该使用双等于号比较
开发中比较字符串推荐使用什么方式比较?
使用String提供的equals方法,它只关心字符串内容一样就返回true
方法名→
public boolean equals (Object anObject)
public boolean equalsIgnoreCase(String anotherString)
public static void main(java.lang.String[] args) {
// 1、开发一个登录界面
for (int i = 0; i < 3; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("请您输入登录名称:");
java.lang.String loginName = sc.next();
System.out.println("请您输入登录密码:");
java.lang.String passWord = sc.next();
// 5、开始调用登录方法,判断是否登录成功
boolean rs = login(loginName, passWord);
if(rs){
System.out.println("恭喜您,欢迎进入系统~~");
break; // 跳出for循环,代表登录完成
}else {
System.out.println("登录名或者密码错误,请您确认~~");
}
}
}
/**
2、开发一个登录方法,接收用户的登录名和密码,返回认证的结果
*/
public static boolean login(java.lang.String loginName, java.lang.String passWord){
// 3、准备一份系统正确的登录名和密码
java.lang.String okLoginName = "itheima";
java.lang.String okPassWord = "123456";
// 4、开始正式判断用户是否登录成功
/*if(okLoginName.equals(loginName) && okPassWord.equals(passWord)){
// 登录成功的
return true; }else { return false; }*/
return okLoginName.equals(loginName) && okPassWord.equals(passWord);
}
String的应用案例2 开发验证码
- 需求:
实现随机产生验证码,验证码的每位可能是数字、大写字母、小写字母。 - 分析:
1、设计一个方法,该方法接收一个整型参数,最终要返回对应位数的随机验证码
2、方法内定义2个字符串变量:1个用来记住生成的验证码,1个用来记住要用到的全部字符
3、定义for循环控制生成多少位随机字符,每次得到一个字符范围内的随机索引,根据索引提取该字符,把该字符交给code变量连接起来,循环结束后,在循环外返回code即可
public static java.lang.String createCode(int n){
// 2、定义2个变量 一个是记住最终产生的随机验证码 一个是记住可能用到的全部字符
java.lang.String code = "";
java.lang.String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random r = new Random();
// 3、开始定义一个循环产生每位随机字符
for (int i = 0; i < n; i++) {
// 4、随机一个字符范围内的索引。
int index = r.nextInt(data.length());
// 5、根据索引去全部字符中提取该字符
code += data.charAt(index); // code = code + 字符
}
// 6、返回code即可
return code;
}
ArrayList类
- 什么是集合?
集合是一种容器,用来装数据,类似于数组。但不同于长度固定的数组,集合大小可变,开发中用的最多。集合的种类很多诸如ArrayList、HashSet、List等等,基于常用的集合以下展开对ArrayList的描述 - ArrayList集合该怎么学呢?
1、会提供创建容器对象的方式
2、会提供相应的方法对容器进行操作
增删查改!
他可以1、创建对象 2、增删改查的方法 3、容器的其他特点 ArrayList<E>
是用的最多、最常见的一种集合。
1、构造器及说明:
public ArrayList()
创建一个空的集合对象
2、常用方法名及说明:
public boolean add(E e)
将指定的元素添加到此集合的末尾
public void add(int index,E element)
在此集合中的指定位置插入指定的元素
public E get(int index)
返回指定索引处的元素
public int size()
返回集合中的元素的个数
public E remove(int index)
删除指定索引处的元素,返回被删除的元素
public boolean remove(Object o)
删除指定的元素,返回删除是否成功
public E set(int index,E element)
修改指定索引处的元素,返回被修改的元素
// 1、创建一个ArrayList的集合对象
// ArrayList<String> list = new ArrayList<String>();
// 从jdk 1.7开始才支持的
ArrayList<java.lang.String> list = new ArrayList<>();
list.add("黑马");
list.add("黑马");
list.add("Java");
System.out.println(list);
// 2、往集合中的某个索引位置处添加一个数据
list.add(1, "MySQL");
System.out.println(list);
// 3、根据索引获取集合中某个索引位置处的值
java.lang.String rs = list.get(1);
System.out.println(rs);
// 4、获取集合的大小(返回集合中存储的元素个数)
System.out.println(list.size());
// 5、根据索引删除集合中的某个元素值,会返回被删除的元素值给我们
System.out.println(list.remove(1));
System.out.println(list);
// 6、直接删除某个元素值,删除成功会返回true,反之
System.out.println(list.remove("Java"));
System.out.println(list);
list.add(1, "html");
System.out.println(list);
// 默认删除的是第一次出现的这个黑马的数据的
System.out.println(list.remove("黑马"));
System.out.println(list);
// 7、修改某个索引位置处的数据,修改后会返回原来的值给我们
System.out.println(list.set(1, "黑马程序员"));
System.out.println(list);
}
ArrayList的应用案例
- 需求:
现在假如购物车中存储了如下这些商品:Java入门,宁夏枸杞,黑枸杞,人字拖,特级枸杞,枸杞子。现在用户不想买枸杞了,选择了批量删除,请完成该需求 - 分析:
1、后台使用ArrayList集合表示购物车,存储这些商品名
2、遍历集合中的每个数据,只要这个数据包含了“枸杞”则删除它
3、输出集合看是否已经成功删除了全部枸杞数据了 - 从集合中遍历元素,并筛选出元素删除它,应该如何操作才能不出bug?
方式一:每次删除一个数据后,索引-1
方式二:从集合后面遍历然后删除,可以避免漏掉元素 - 具体代码如下所示:
public static void main(java.lang.String[] args) {
// 1、创建一个ArrayList集合对象
ArrayList<java.lang.String> list = new ArrayList<>();
list.add("枸杞");
list.add("Java入门");
list.add("宁夏枸杞");
list.add("黑枸杞");
list.add("人字拖");
list.add("特级枸杞");
list.add("枸杞子");
System.out.println(list);
// [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]
// [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]
// [Java入门, 黑枸杞, 人字拖, 枸杞子]
// i
// 2、开始完成需求:从集合中找出包含枸杞的数据并删除它
/* for (int i = 0; i < list.size(); i++) {
// i = 0 1 2 3 4 5 // 取出当前遍历到的数据
String ele = list.get(i); // 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele); } } System.out.println(list);*/
// [Java入门, 人字拖]
// i
// 方式一:每次删除一个数据后,就让i往左边退一步
/* for (int i = 0; i < list.size(); i++) {
// i = 0 1 2 3 4 5 // 取出当前遍历到的数据
String ele = list.get(i); // 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele); i--; } }
System.out.println(list);*/
// 方式二:从集合的后面倒着遍历并删除
// [Java入门, 人字拖]
// i for (int i = list.size() - 1; i >= 0; i--) {
// 取出当前遍历到的数据
java.lang.String ele = list.get(i);
// 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele);
}
}
System.out.println(list);
}
ArrayList的综合案例 模仿外卖系统中的商家系统
- 需求:
完成菜品的上架、以及菜品信息浏览功能 - 目标:
使用所学的ArrayList集合结合面向对象编程实现以上2个需求 - 步骤:
1、设计一个菜品类Food,负责创建菜品对象,封装菜品数据。注意定义好get&set以及有参和无参的构造器
2、设计一个菜品操作类FoodOperator,负责完成对菜品的业务实现:上架,浏览信息。使用集合为容器来接收各个菜品,分别设置好上架、浏览信息和操作界面的方法 - 具体代码如下所示:
public class ArrayListTest2menuDemo {
public static void main(java.lang.String[] args) {
// 目标:完成拓展案例:商家菜品上架操作。
// 1、设计一个菜品类Food,负责创建菜品对象,封装菜品数据。
// 2、设计一个菜品操作类FoodOperator,负责完成对菜品的业务实现:上架,浏览信息
FoodOperator operator = new FoodOperator();
operator.start();
}
}
public class Food {
private java.lang.String name;
private double price;
private java.lang.String desc; // 描述
public Food() {
}
public Food(java.lang.String name, double price, java.lang.String desc) {
this.name = name;
this.price = price;
this.desc = desc;
}
public java.lang.String getName() {
return name;
}
public void setName(java.lang.String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public java.lang.String getDesc() {
return desc;
}
public void setDesc(java.lang.String desc) {
this.desc = desc;
}
}
import java.util.ArrayList;
import java.util.Scanner;
public class FoodOperator {
// 1、定义一个ArrayList集合对象,负责存储菜品对象信息
private ArrayList<Food> foodList = new ArrayList<>();
// foodList = []
// 2、开发功能:上架菜品功能。
public void addFood(){
// 3、创建一个菜品对象,封装上架的菜品信息
Food f = new Food();
// 4、录入菜品信息进去
Scanner sc = new Scanner(System.in);
System.out.println("请您输入该菜品名称:");
java.lang.String name = sc.next();
f.setName(name);
System.out.println("请您输入该菜品价格:");
double price = sc.nextDouble();
f.setPrice(price);
System.out.println("请您输入该菜品描述:");
java.lang.String desc = sc.next();
f.setDesc(desc);
// 5、把菜品对象存入到集合中去
foodList.add(f);
System.out.println("上架成功!");
}
// 6、展示菜品
// foodList = [f1, f2, f3, ... ]
// i public void showAllFoods(){
if(foodList.size() == 0) {
System.out.println("什么菜品都么有,先去上架!!");
return;
}
for (int i = 0; i < foodList.size(); i++) {
Food f = foodList.get(i);
System.out.println(f.getName());
System.out.println(f.getPrice());
System.out.println(f.getDesc());
System.out.println("-----------------");
}
}
/** 负责展示操作界面。 */
public void start(){
while (true) {
System.out.println("请选择功能:");
System.out.println("1、上架菜品");
System.out.println("2、展示菜品");
System.out.println("3、退出");
Scanner sc = new Scanner(System.in);
System.out.println("请选择您的操作:");
java.lang.String command = sc.next();
switch (command) {
case "1":
addFood();
break;
case "2":
showAllFoods();
break;
case "3":
System.out.println("下次再来哦!");
return; // 干掉方法!
default:
System.out.println("您输入的命令不存在!");
}
}
}
}