文章目录
前言
数据在计算机底层都是都是采用二进制:使用0、1,按照逢2进1的规则表示数据来存储。
计算机底层表示数据的最小单元是字节,一个字节等于8个二进制位:1B=8b
字符在计算机中是存储对应的ASCII编码eg:A对应的ASCII编码是65,A对应的ASCII编码是90,a对应的ASCII编码是97,数字0对应的ASCII编码是48。
// 1、字符的存储原理:存储的是字符编号的二进制
System.out.println('a' + 1); //a的ascill码对于的数字是97,则输出98
System.out.println('A' + 1); //A的ascill码对于的数字是65,则输出66
System.out.println('0' + 1); //0的ascill码对于的数字是48,则输出49
// 2、程序中书写 二进制 八进制 十六进制
int a1 = 0B11111010; //二进制用 0B或0b开头
System.out.println(a1);
int a2 = 0372; //八进制用 0开头
System.out.println(a2);
int a3 = 0XFA; //十六进制用 0X或0x开头
System.out.println(a3);
一、Java变量、类型转换、常用运算符
①基本数据类型
代码如下(示例):
基本语法:
数据类型 变量名称 = 初始值;
// 1、byte 字节整形
byte age =12;
// 2、short 短整形
short number1 = 32323;
// 3、int 整形(默认)
int number2 = 424242424;
// 4、long 长整型
long lg = 434343434332324L; //要在后面加上L或l
// 5、float 单精度浮点数
float ft = 3.14F; //要在后面加上F或f
// 6、double 双精度浮点数(默认)
double score =3.14;
// 7、char 字符型
char a1 = 'A';
char a2 = '中';
// 8、boolean 布尔型
boolean flag1 = true;
boolean flag2 = false;
②自动类型转换 :类型范围小的变量,可以直接赋值给类型范围大的变量。
强制类型转换:强行将类型范围大的变量、数据赋值给类型范围小的变量
代码如下(示例):
//自动类型转换
byte 、short、char -> int -> long -> float -> double
byte a = 12;
int b = a;
System.out.println(b); // 因为b的数据类型是int,返回12
int i = 999;
double j = i;
System.out.println(j); // 因为j的数据类型是double,返回999.0
char ch = 'b';
int it = ch;
System.out.println(ch); // 因为ch的数据类型是char,所以返回b
System.out.println(it); // 同理,it的数据类型是int,所以返回98
注意:
表达式的最终结果类型由表达式中的最高类型决定。
在表达式中,byte、short、char 是直接转换成int类型参与运算的。
//强制类型转换
基本语法:
数据类型 变量 = (数据类型)变量、数据
int a = 20;
byte b = (byte)a; //结果是20,具体解释可参考强制类型转换在计算机中的执行原理
int i = 1500;
byte j = (byte)i; //结果是-36,具体解释可参考强制类型转换在计算机中的执行原理
注意:
强制类型转换可能造成数据(丢失)溢出;
浮点型强转成整型,直接丢掉小数部分,保留整数部分返回
③常用运算符:主要有算术、自增自减、赋值、关系、逻辑、三元运算符
代码如下(示例):
算数运算符:+(相加)、-(相减)、*(相乘)、
/(整除):常用来算一个数的某个分位……
%(求余数):常用来求奇偶数、素数……
System.out.println(i / j); //想得到整数
System.out.println(1.0 * i / j); //想得到小数,就这样写
// + 符号可以做连接符,能算则加,不能算就拼接到一起
int a = 5;
System.out.println("abcd" + 5); //结果是abcd5
System.out.println(a + 5); //结果是10
System.out.println("abcd" + 5 + 'a'); //结果是abcd5a
System.out.println(5 + 'a' + "abcd");
//结果是102abcd,因为数据类型是int,所以5 + 'a'会变成5+97
自增自减运算符:++、--
int a = 10;
a++; //a = a + 1 单独使用的时候 他们相同
++a; //a = a + 1
//当表达式中出现自增、自减运算符时,注意前后
int i = 10;
int j = 4;
int rs1 = ++i; //++在前,先加后算。
int rs2 = j++; //++在后,先算再加
System.out.println(i); //结果是11
System.out.println(rs1); //结果是11
System.out.println(j); //结果是5
System.out.println(rs2); //结果是4
赋值运算符:+=、-+、*=、/+、%=
//赋值运算符可以自带强制类型转换,不用自己手动操作
int a = 10;
int b = 100;
a += b; //等价于 a = (a的类型)(a + b) 底层代码会自动转成a的类型
System.out.println(a); //结果是110
关系运算符:>、>=、<、<=、==、!=
int i = 10;
int j = 3;
System.out.println(i > j); //结果是true
System.out.println(i == j); //结果是false
逻辑运算符☆: 逻辑运算符 &(逻辑与)、|(逻辑或)、 !(取反)、 ^(异或)、&&(短路与)、||(短路或)
1、&:两边都为true,结果才为true
2、|:一边为true,结果为true
3、!:取反
System.out.println(!(2>1));
4、^异或:前后条件一致为false,前后条件不一致才true
System.out.println(true ^ true);
实际开发中使用的多
5、&& 结果与&一致,但过程不一样,若&&左边是false,则右边不执行,性能高一点
int i1 =10;
int j1 = 555;
//System.out.println(i<1 & ++j >333); // j1是556,
System.out.println(i1<1 && ++j1 >333); //j1是555
6、|| 结果与|一致,但过程不一样,若||左边是true,则右边不执行
System.out.println(i1 >9 || ++j1 >444);
System.out.println(j1); // j1为555
三元运算符: 条件表达式 ? 值1 : 值2;
int a = 10;
int b = 1888;
int rs = a > b ? a : b; //a > b为真,返回a,为假返回b
System.out.println("较大值1是:" + rs);
运算符优先级:
二、程序流程控制
程序中最经典的三种执行顺序
顺序结构:自上而下的执行
分支结构:根据条件,选择对应代码执行
循环结构:控制某段代码重复执行
1.分支结构
是为了进行条件判断
if分支:根据条件(真、假)来决定执行某段代码。 例如:37.2℃以上是发烧,以下不是
if分支代码如下(示例):
//1、单分支
double t = 36.5;
if (t > 37.2) {
System.out.println("你的体温异常!");
}
System.out.println("检查结束");
double money = 100;
if (money > 90) {
System.out.println("发出红包成功");
} else {
System.out.println("余额不足");
}
//2、多分支:条件为区间,常用
Scanner sc = new Scanner(System.in);
System.out.println("请输入成绩:");
double score = sc.nextDouble();
if (score >= 90 && score <= 100) {
System.out.println("A");
} else if (score >= 80 && score < 90) {
System.out.println("B");
} else if (score >= 70 && score < 80) {
System.out.println("C");
} else {
System.out.println("你的输入有误");
}
//3、switch分支:匹配单个值,常用
Scanner sc1 = new Scanner(System.in);
System.out.println("请你输入今天是周几");
String weekDay = sc1.next();
switch (weekDay){
case "周一":
System.out.println("埋头苦干,解决bug");
break;
case "周二":
System.out.println("请技术大牛帮忙");
break;
case "周三":
case "周四":
System.out.println("主动帮新来的女程序员解决bug");
break;
case "周五":
System.out.println("今晚吃鸡");
break;
case "周六":
System.out.println("与小芳约会");
break;
case "周日":
System.out.println("郁郁寡欢,准备上班");
break;
default:
System.out.println("输入信息错误");
}
}
注意:
表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、不支持double、float、long。
case给出的值不允许重复,且只能是字面量,不能是变量。
正常使用switch的时候,不要忘记写break
2.循环结构
是为了减少代码的重复编写,灵活的控制程序的执行。
for循环代码如下(示例):
For循环:先判断后执行
打印3遍 Hello World1
for (int i = 0; i < 3; i++) {
System.out.println("Hello World1");
}
求1-5的数字和。
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
}
System.out.println("求和的结果是:" + sum);
执行顺序:
第一次i=1进行判断i <= 5,然后执行一次,sum += i(sum=0+1);,然后i++变成2;
第二次i=2进行判断i <= 5,然后执行一次,sum += i(sum=0+1+2);,然后i++变成3;
第三次i=3进行判断i <= 5,然后执行一次,sum += i(sum=0+1+2+3);,然后i++变成4;
第四次i=4进行判断i <= 5,然后执行一次,sum += i(sum=0+1+2+3+4);,然后i++变成5;
第五次i=5进行判断i <= 5,然后执行一次,sum += i(sum=0+1+2+3+4+5);,然后i++变成6;
第六次i=6进行判断i <= 5,不成立,循环结束。
while循环代码如下(示例):
while循环:先判断后执行
int i = 0;
int sum =0 ;
while(i <= 5){
sum +=i;
i++;
}
System.out.println(sum);
如何选择两种循环语句的使用?
while能做的for都能实现,for能做的while也都能实现,功能上无区别。
使用规范:如果一开始不知道循环次数的情况下,建议使用while循环解决更好。
一开始就知道循环几次的情况下,使用for循环来解决更好。
do-while循环代码如下(示例):
do while循环:先执行后判断
int i = 0;
do {
System.out.println("Hello World");
i++;
} while (i < 3);
上来先执行一次{}里的语句,然后再进行判断。
使用场景:当你是一个程序员,你想写一个抢比赛门票,一上来就要先抢票,没抢到再继续抢。
死循环代码如下(示例):
第一种:
for (;;){
System.out.println("Hello World");
}
第二种:
while死循环(经典写法) 服务器里的程序会用到(因为任何时间都有人访问).
while (true) {
System.out.println("Hello World");
}
第三种:
do while死循环
do {
}while(true);
嵌套循环代码如下(示例):
for (int i = 0; i <= 3; i++) {
for (int j = 0; j <= 4; j++) {
System.out.print("☆");
}
System.out.println();
}
执行结果:
第一层外层循环,i=0,判断i <= 3,
然后执行内层循环,j=0时,判断j <= 4,成立则打印出一个☆,然后j++;
接着内层继续进行循环,这个时候j=1,再判断j <= 4,成立则打印出一个☆,然后j++;
等到j=5的时候,不满足条件,结束内层循环,执行下面的语句System.out.println(); ->换行
则第一次循环打印出了☆☆☆☆☆,
以此类推,外层循环进行了4次,
结果为:
☆☆☆☆☆
☆☆☆☆☆
☆☆☆☆☆
☆☆☆☆☆
跳转关键字:
break : 跳出并结束当前所在循环的执行。
continue: 用于跳出当前循环的当次执行,直接进入循环的下一次执行
注意:
break : 只能用于结束所在循环, 或者结束所在switch分支的执行。
continue : 只能在循环中进行使用。
3.猜字小游戏案例
需求:随机生成一个1-100之间的数据,提示用户猜测,猜大提示过大,猜小提示过小,直到猜中结束游戏。
代码如下(示例):
// 目标:猜数字游戏的案例。
// 1、得到1-100之间的一个随机数作为幸运号码
Random r = new Random();
int luckNumber = r.nextInt(100) + 1;
// 2、使用一个死循环让用户开始猜测
Scanner sc = new Scanner(System.in);
while (true) {
// 3、让当前这个用户输入一个猜测的数字
System.out.println("请您输入您猜测的数字:");
int guessNumber = sc.nextInt();
// 4、判断猜测的情况
if(guessNumber > luckNumber) {
System.out.println("猜大了~~");
}else if(guessNumber < luckNumber) {
System.out.println("猜小了~~");
}else {
System.out.println("恭喜您,猜对了,去买单吧!");
break; // 跳出循环的!
}
}
三、数组
1.认识数组
①什么是数组
数组就是一个容器,用来存一批同种类型的数据的。
比如:想要存储 20,10,80,60,90 这些数据。 我们可以把代码写成这样
int[] array = {20,10,80,60,90};
②数组的应用场景
需要大量定义变量的时候,用数组能使代码更简洁、逻辑更清楚,所以遇到批量数据的存储和操作时,数组比变量更适合。
2.数组的定义和访问
数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。我们先用静态初始化来学习数组的操作。
①数组的静态初始化数组
所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。
//定义数组,用来存储多个年龄
int[] ages = new int[]{11,22,33}
可以简写成:int[] ages = {11,22,33}
也可以写成:int ages[] = {11,22,33}
//定义数组,用来存储多个成绩
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};
可以简写成:double[] scores = {89.9, 99.5, 59.5, 88.0};
也可以写成:double scores[] = {89.9, 99.5, 59.5, 88.0};
②数组的动态初始化
动态初始化不需要我们写出具体的元素,而是指定元素类型和长度就行。
//数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[13];
使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。
③数组的初始化
静态数组初始化
int[] arr = {12, 24, 36};
索引: 0 1 2
// 1、访问数组的全部数据
System.out.println(arr[0]); //12
System.out.println(arr[1]); //24
System.out.println(arr[2]); //36
修改数组中的数据
arr[0] = 11;
arr[2] = 22;
System.out.println(arr[0]); //11
System.out.println(arr[1]); //24
System.out.println(arr[2]); //22
访问数组的元素个数:数组名.length
System.out.println(arr.length);
获取数组的最大索引: arr.length - 1(前提是数组中存在数据)
System.out.println(arr.length - 1);
遍历数组
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
System.out.println(ages[i]);
}
动态数组初始化
double[] scores = new double[6];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
double score = sc.nextDouble();
scores[i] = score; //手动输入的成绩,都存入scores 数组中了
}
④多个变量指向同一个数组的问题
int[] arr1 = {11, 22, 33};
// 把int类型的数组变量arr1赋值给int类型的数组变量arr2
int[] arr2 = arr1;
System.out.println(arr1); //arr1和arr2返回的地址一致
System.out.println(arr2);
arr2[1] = 99;
System.out.println(arr1[1]);
//结果是99,因为arr2和arr1都在栈内存中,他们都指向堆内存中对于的值,
值改变,他们访问到的值也变了
arr2 = null; // 拿到的数组变量中存储的值是null
System.out.println(arr2);
//System.out.println(arr2[0]); //地址指向null后,表示没有地址,就访问不到元素了
四、方法
1.方法概述
①方法是什么
方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用。
② 为什么要使用方法,好处是什么
1、提高了代码的复用性,提高了开发效率。
2、程序的逻辑更清晰。
简单来说:写好一个方法之后,每一个人都可以直接调用,而不用再重复写相同的代码。所以是提高了代码的复用性,不用写重复代码,自然也提高了开发效率。
③方法的完整格式
//格式如下:
修饰符 返回值类型 方法名( 形参列表 ){
方法体代码(需要执行的功能代码)
return 返回值;
}
//调用格式:
方法名(...);
示例:写一个方法,找出两个值中的较大值
public static void main(String[] args) {
int max =getMax(10,30);
System.out.println("较大值是:" + max);
}
public static int getMax(int a, int b) {
int max = a > b ? a : b;
return max;
}
④设计一个合理的方法的原则如下:
1、如果方法不需要返回数据,返回值类型必须申明成void(无返回值申明), 此时方法内部不可以使用return返回数据。
2、方法如果不需要接收外部传递进来的数据,则不需要定义形参,且调用方法时也不可以传数据给方法。
3、没有参数,且没有返回值类型(void)的方法,称为值无参数、无返回值方法。此时调用方法时不能传递数据给方法。
2.方法的案例
①求1-n的和
public static void main(String[] args) {
int rs = add(5);
System.out.println("1-5的和是:" + rs); //15
int rs = add(6);
System.out.println("1-6的和是:" + rs); //21
}
public static int add(int n){
int sum = 0;
for (int i = 1; i <= n; i++) {
// i = 1 2 3 ... n
sum += i;
}
return sum;
}
②判断一个整数是奇数还是偶数
public static void main(String[] args) {
judge(7); //调用后打印:7是一个奇数
judge(8); //调用后打印:8是一个偶数
}
public static void judge(int number){
if(number % 2 == 0){
System.out.println(number + "是一个偶数!");
}else {
System.out.println(number + "是一个奇数!");
}
}
3.方法参数的传递机制
结论:Java的参数传递机制都是:值传递
①参数传递的基本类型数据
Java的参数传递机制都是:值传递,传递的是实参存储的值的副本
②参数传递的是引用数据类型
实际上也是值传递,只不过参数传递存储的地址值
③案例:输出一个int类型的数组内容,要求输出格式为:[11, 22, 33, 44, 55]。
public static void main(String[] args) {
// 目标:完成打印int类型的数组内容。
int[] arr = {10, 30, 50, 70};
printArray(arr);
int[] arr2 = null;
printArray(arr2);
int[] arr3 = {};
printArray(arr3);
}
/*
参数:int[] arr表示要被打印元素的数组,需要调用者传递
*/
public static void printArray(int[] arr){
if(arr == null){
System.out.println(arr); // null
return; // 跳出当前方法
}
System.out.print("[");
// 直接遍历接到的数组元素
for (int i = 0; i < arr.length; i++) {
if(i == arr.length - 1){
System.out.print(arr[i]);
}else {
System.out.print(arr[i] + ", ");
}
}
System.out.println("]");
}
4.方法重载
所谓方法重载指的是:一个类中,出现多个相同的方法名,但是它们的形参列表是不同的。
示例:
public static void main(String[] args) {
test();
test(100);
}
//一个类中,重载一个方法,只能有一个用public,别的都不可以用
public static void test(){
System.out.println("===test1===");
}
public static void test(int a){
System.out.println("===test2===" + a);
}
void test(double a){
}
void test(double a, int b){
}
void test(int b, double a){
}
int test(int a, int b){
return a + b;
}
5.return单独使用
public static void main(String[] args) {
System.out.println("开始");
chu(10 , 0);
System.out.println("结束");
}
public static void chu(int a , int b){
if(b == 0){
System.err.println(“您的数据有误!!不执行!!”);
return; // 直接跳出并结束当前除法方法的执行
}
int c = a / b;
System.out.println("除法结果是:"+c);
}
五、Java编程案例
①用户购买机票时,机票原价会按照淡季、旺季,头等舱还是经济舱的情况进行相应的优惠, 优惠方案如下:5-10月为旺季,头等舱9折,经济舱8.5折; 11月到来年4月为淡季,头等舱7折,经济舱6.5折, 请开发程序计算出用户当前机票的优惠价。
public class Test1 {
public static void main(String[] args) {
double price = calc(1000, 9, "经济舱");
System.out.println("优惠价格是:" + price + "元");
double price2 = calc(1000, 9, "头等舱");
System.out.println("优惠价格是:" + price2 + "元");
}
public static double calc(double price,int month,String type){
if (month >= 5 && month <= 10){
switch (type){
case "头等舱":
price = price * 0.9;
break;
case "经济舱":
price = price * 0.85;
break;
}
}else {
switch (type){
case "头等舱":
price = price * 0.7;
break;
case "经济舱":
price = price * 0.65;
break;
}
}
return price;
}
}
②开发一个程序,可以生成指定位数的验证码,每位可以是数字、大小写字母。
public class Test2 {
public static void main(String[] args) {
System.out.println("四位验证码是:"+createCode(4));
System.out.println("六位验证码是:"+createCode(6));
}
public static String createCode(int length) {
//1、准备一个字符串变量用于拼接每位随机字符作为验证码
String code = "";
Random random = new Random();
//2、使用循环产生每位随机字符
for (int i = 0; i < length; i++) {
//3、为当前位置产生一位随机字符,0表示数字,1表示大写字母,2表示小写字母
int type = random.nextInt(3);
switch (type) {
case 0:
int number = random.nextInt(10);
code += number;
break;
case 1: //A(65) - Z(65+25)
char c1 = (char) (random.nextInt(26) + 65);
code += c1;
break;
case 2: //a(97) - z(97+25)
char c2 = (char) (random.nextInt(26) + 97);
code += c2;
}
}
return code;
}
}
③在唱歌比赛中,可能有多名评委要给选手打分,分数是[0 - 100]之间的整数。 选手最后得分为:去掉最高分、最低分后剩余分数的平均分,请编写程序能够录入多名评委的分数,并算出选手的最终得分。
public class Test3 {
public static void main(String[] args) {
double score = start(6);
System.out.println("选手最终得分是:" + score);
}
public static double start(int number) {
double[] scores = new double[number];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < number; i++) {
System.out.println("请输入第" + (i + 1) + "位评委的打分:");
double score = sc.nextDouble();
if (score > 100 || score < 0) {
System.out.println("您输入的分数有误~");
i--; //如果不加这个,那第一个评委就没有输入有效成绩,下一次循环i就从1开始了
continue;
}
scores[i] = score;
}
double max = scores[0];
double min = scores[0];
double sum = scores[0];
for (int i = 1; i < scores.length; i++) {
double score = scores[i];
if (score > max) max = score;
if (score < min) min = score;
sum += score;
}
System.out.println("最高分是:" + max);
System.out.println("最低分是:" + min);
return (sum - max - min) / (number - 2);
}
}
④ 某系统的数字密码是一个四位数,如1983,为了安全,需要加密后再传输。加密规则是:对密码中的每位数,都加5,再对10求余,最后将所有数字顺序反转,得到一串加密后的新数,请设计出满足本需求的加密程序!
public class Test4 {
public static void main(String[] args) {
String result = encode(1983);
System.out.println("加密后的数是:" + result);
}
public static String encode(int number) {
int[] data = new int[4];
data[0] = number / 1000;
data[1] = number / 100 % 10;
data[2] = number / 10 % 10;
data[3] = number % 10;
//加密
for (int i = 0; i < data.length; i++) {
data[i] = (data[i] + 5) % 10;
}
//反转
for (int i = 0, j = data.length - 1; i < j; i++, j--) {
int temp = data[j];
data[j] = data[i];
data[i] = temp;
}
//拼接输出
String st = "";
for (int i = 0; i < data.length; i++) {
st += data[i];
}
return st;
}
}