本文章参考B站 Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题),仅供个人学习使用,部分内容为本人自己见解,与黑马程序员无关。
1、JDK初步理解
jdk、jre、javac,java的关系
Java跨平台原理
因为每个平台都可以安装Java的JVM,程序在JVM中执行
2、Java基础语法
2.1、注释
2.2、字面量
2.3、变量
2.4、数据类型
验证整数默认为int, 小数默认为double
public class TestData {
public static String getType(Object o){
return o.getClass().toString(); // 使用Object的getClass()方法
}
public static void main(String[] args) {
System.out.println(getType(2));
System.out.println(getType(3.14));
}
}
输出结果:
class java.lang.Integer
class java.lang.Double
浮点数相加会出现精度问题
public class TestDouble {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
System.out.println(a + b);
}
}
输出结果:
0.30000000000000004
解决方法:使用BigDecimal
import java.math.BigDecimal;
public class TestDouble {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
System.out.println(a + b);
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
double value = b1.add(b2).doubleValue();
System.out.println(value);
}
}
输出结果:
0.30000000000000004
0.3
2.5、ASCII 编码表
字符当整数使用案例
public class ASCIIDemo {
public static void main(String[] args) {
char ch = 'a'; //
// ch = 00000000 01100001
System.out.println(ch + 10); // 97 + 10
}
}
输出结果:
107
2.6、关键字、标志符
关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
2.7、字符、图片、声音在计算机中的底层原理
字符
图片
声音
2.8、Java 书写二进制、八进制、十六进制
代码演示
public class TestData {
public static void main(String[] args) {
int i1 = 0B01100001;
System.out.println(i1);
int i2 = 0141;
System.out.println(i2);
int i3 = 0x61;
System.out.println(i3);
}
}
运行结果:
97
97
97
3、类型转换、常用运算符、键盘录用技术
3.1、类型转换
常见面试题
byte、short、char直接提升成int运算的
byte i = 100;
byte j = 120;
int k = i + j;
// 需强制转换,可能丢失进度
byte b = (byte) (i + j);
需求:拆分3位数,把个位、十位、百位分别输出
public class OperatorTest2 {
public static void main(String[] args) {
// 需求:拆分3位数,把个位、十位、百位分别输出
int data = 589;
// 1、个位
int ge = data % 10;
System.out.println(ge);
// 2、十位
int shi = data / 10 % 10;
System.out.println(shi);
// 3、百位
int bai = data / 100;
System.out.println(bai);
}
}
3.2、运算符
&、&&,|、|| 的区别
&:即使第一个条件是false,依然执行后面的条件
&&:第一个条件是false,后面条件不执行,性能好一点
|:即使第一个条件是true,依然执行后面的条件
||:第一个条件是true,后面条件不执行,性能好一点
注意:开发一般使用&&、||
运算符优先级
3.3、键盘录用技术 (Scanner类)
next()、nextLine() 的区别
next():
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
nextLine():
- 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
- 2、可以获得空白。
4、程序流程控制
4.1、分支结构
if 和 switch 的区别
- 都是做分支操作的;
- if 的功能更强大,适合做区间匹配
- 如果是值匹配的操作建议用 switch, 格式清晰,性能较好
switch 的穿透性
public class SwitchDemo4 {
public static void main(String[] args) {
// 需求:用户输入月份可以展示该月份的天数。
// 1、3 、5、 7 、 8、 10、 12月份是 31天
// 2月份是闰年为29天、非闰年为28天。
// 4 、6 、9、 11月份 是30天
int month = 7;
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println(month +"是31天!");
break;
case 2:
System.out.println(month +"月闰年为29天、非闰年为28天!");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println(month +"是30天!");
break;
default:
System.out.println("数据有误!");
}
}
}
输出结果:
7是31天!
4.2、循环结构
for、while 的使用
- 知道循环几次使用for
- 不知道循环几次用while循环
水仙花案例
需求:在控制台输出所有的“水仙花数”,水仙花数必须满足如下2个要求:
1. 水仙花数是一个三位数
2. 个位、十位、百位的数字立方和等于原数
public class ForTest4 {
public static void main(String[] args) {
/*
需求:在控制台输出所有的“水仙花数”,水仙花数必须满足如下2个要求:
1. 水仙花数是一个三位数
2. 水仙花数的个位、十位、百位的数字立方和等于原数
*/
// 在循环外定义一个变量用于记录水仙花的个数
int count = 0;
// 1、定义一个for循环找出全部三位数
for (int i = 100; i <= 999; i++) {
// 2、判断这个三位数是否满足要求
// i = 157
// 个位
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+"\t");
count++;
}
}
System.out.println(); // 换行!
System.out.println("水仙花个数是:" + count);
}
}
输出结果:
153 370 371 407
水仙花个数是:4
珠穆朗玛峰案例
需求:
世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,折叠多少次,可以折成珠穆朗玛峰的高度。
public class WhileTest6 {
public static void main(String[] args) {
// 世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。
// 请问,折叠多少次,可以折成珠穆朗玛峰的高度。
// 1、定义变量记录山峰的高度 纸张的厚度
double peakHeight = 8848860;
double paperThickness = 0.1;
// 3、定义一个变量用于记录纸张折叠的次数
int count = 0;
// 2、定义一个while循环控制纸张进行折叠
while (paperThickness < peakHeight){
// 让纸张的厚度多一倍
paperThickness *= 2;
count++;
}
System.out.println("折叠的次数:" + count);
System.out.println("纸张的最终厚度:" + paperThickness);
}
}
输出结果:
折叠的次数:27
纸张的最终厚度:1.34217728E7
4.3、跳转关键字:break、continue
4.4、随机数Random类使用
重点:理解减加法
java17新特性
生成一个区间的随机数
java8,java11,java16 均没发现 implements RandomGenerator,无法使用该方法
java8:
java11:
java16:
Random 案例
import java.util.Random;
import java.util.Scanner;
public class RandomTest2 {
public static void main(String[] args) {
// 1、随机一个幸运号码 1- 100之间 (0 - 99) + 1
Random r = new Random();
int luckNumber = r.nextInt(100) + 1;
// 2、使用一个死循环让用户不断的去猜测,并给出提示
Scanner sc = new Scanner(System.in);
while (true) {
// 让用户输入数据猜测
System.out.println("请您输入猜测的数据(1-100):");
int guessNumber = sc.nextInt();
// 3、判断这个猜测的号码与幸运号码的大小情况
if(guessNumber > luckNumber){
System.out.println("您猜测的数据过大~");
}else if(guessNumber < luckNumber){
System.out.println("您猜测的数据过小");
}else {
System.out.println("恭喜您,猜中了,可以去买单了~~~");
break; // 直接跳出并结束当前死循环!!
}
}
}
}
5、数组
5.1、数组元素的默认值
5.2、常见案例
需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。
public class Test1 {
public static void main(String[] args) {
/*
需求:
某部门5名员工的销售额分别是:16、26、36、6、100
请计算出他们部门的总销售额。
*/
// 1、把这些数据拿到程序中使用数组记住
int[] money = {16, 32, 8, 100, 78};
// 3、定义一个求和变量累加数组的元素值
int sum = 0;
// 2、遍历数组中的每个元素
for (int i = 0; i < money.length; i++) {
// 拿到每个元素值累加
sum += money[i];
}
// 4、输出求和变量即可
System.out.println("数组的元素和是:" + sum);
}
}
输出结果:
数组的元素和是:234
需求:数组元素求最值。
public class Test2 {
public static void main(String[] args) {
// 需求:数组元素求最值。
// 1、定义一个静态初始化的数组,存储一批颜值。
int[] faceScore = {15, 9000, 10000, 20000, 9500, -5};
// 0 1 2 3 4 5
// 2、定义一个变量用于存储最大值元素,建议使用第一个元素作为参照。
int max = faceScore[0];
// 3、遍历数组的每个元素,依次与最大值变量的数据比较,若较大,则替换。
for (int i = 1; i < faceScore.length; i++) {
if(faceScore[i] > max){
max = faceScore[i];
}
}
// 4、输出最大值变量存储的数据即可。
System.out.println("颜值的最大值是:" + max);
}
}
输出结果:
颜值的最大值是:20000
需求:5个 1-20之间的随机数,让用户猜测,猜中要提示猜中,还要输出该数据在数组中第一次出现的索引,并打印数组的内容出来。
public class Test3 {
public static void main(String[] args) {
// 需求:5个 1-20之间的随机数,让用户猜测,猜中要提示猜中,还要输出该数据在数组中第一次出现的索引,并打印数组的内容出来。
// 没有猜中继续。
// 1、定义一个动态初始化的数组存储5个随机的1-20之间的数据
int[] data = new int[5];
// 2、动态的生成5个1-20之间的随机数并存入到数组中去。
Random r = new Random();
for (int i = 0; i < data.length; i++) {
// i = 0 1 2 3 4
data[i] = r.nextInt(20) + 1;
}
// 3、使用一个死循环让用户进行猜测
Scanner sc = new Scanner(System.in);
OUT:
while (true) {
System.out.println("请您输入一个1-20之间的整数进行猜测:");
int guessData = sc.nextInt();
// 4、遍历数组中的每个数据,看是否有数据与猜测的数据相同,相同代表猜中了,给出提示
for (int i = 0; i < data.length; i++) {
if(data[i] == guessData){
System.out.println("您已经猜中了该数据,运气不错了!您猜中的数据索引是:" + i);
break OUT; // 结束了整个死循环,代表游戏结束了!
}
}
System.out.println("当前猜测的数据在数组中不存在,请重新猜测!");
}
// 5、输出数组的全部元素,让用户看到自己确实是猜中了某个数据。
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
}
}
目标:键盘录入一组工号,最终要随机输出一组出来作为排名
public class Test4 {
public static void main(String[] args) {
// 目标:键盘录入一组工号,最终要随机输出一组出来作为排名
// 1、动态初始化一个数组,存储5个工号
int[] codes = new int[5];
// 2、定义一个循环,循环5次,依次录入一个工号存入对应的位置
Scanner sc = new Scanner(System.in);
for (int i = 0; i < codes.length; i++) {
// 正式录入工号
System.out.println("请您输入第" + (i + 1) + "个员工的工号:");
int code = sc.nextInt();
// 存入到数组中去
codes[i] = code;
}
// 3、遍历数组中的每个元素,然后随机一个索引出来,让该元素与随机索引位置处的元素值进行交换(本节的重点)
// codes = [12, 36, 28, 45, 99]
Random r = new Random();
for (int i = 0; i < codes.length; i++) {
// 当前遍历的元素值:codes[i]
// 随机一个索引位置出来:codes[index]
int index = r.nextInt(codes.length);
// 定义一个临时变量存储index位置处的值
int temp = codes[index];
codes[index] = codes[i];
codes[i] = temp;
}
// 4、遍历数组元素输出就是随机排名的结果
for (int i = 0; i < codes.length; i++) {
System.out.print(codes[i] + "\t");
}
}
}
冒泡排序
public class Test5 {
public static void main(String[] args) {
// 1、定义一个数组,存储一些数据啊
int[] arr = {5, 2, 3, 1};
// 0 1 2 3
// 2、定义一个循环控制比较的轮数
for (int i = 0; i < arr.length - 1; i++) {
// i == 0 比较的次数 3 j = 0 1 2
// i == 1 比较的次数 2 j = 0 1
// i == 2 比较的次数 1 j = 0
// 3、定义一个循环控制每轮比较的次数,占位
for (int j = 0; j < arr.length - i - 1; j++) {
// 判断j当前位置的元素值 是否 大于后一个位置 若较大 则交换
if(arr[j] > arr[j+1]) {
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
// 遍历数组内容输出
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
输出结果:
1 2 3 5
5.3、数组的内存图
补充:JVM的体系结构(图片源自狂神说JVM)
数组的 NullPointerException 异常
public class Test {
public static void main(String[] args) {
int[] arr = null;
System.out.println(arr);
System.out.println(arr.length);
}
}
输出结果:
6、方法
6.1、方法的参数传递机制
基本类型的参数传递案例
public class MethodDemo1 {
public static void main(String[] args) {
// 目标:理解Java的基本类型的参数传递:值传递。
int a = 10;
change(a);
System.out.println(a); // 10
}
public static void change(int a){
System.out.println(a); // 10
a = 20;
System.out.println(a); // 20
}
}
输出结果:
10
20
10
原理:
引用类型的参数传递
public class MethodDemo2 {
public static void main(String[] args) {
// 目标:理解引用类型的参数传递机制:值传递,区分其不同点
int[] arrs = {10, 20, 30};
change(arrs);
System.out.println(arrs[1]); // 222
}
public static void change(int[] arrs){
System.out.println(arrs[1]); // 20
arrs[1] = 222;
System.out.println(arrs[1]); // 222
}
}
输出结果:
20
222
222
原理:
基本类型和引用类型的参数在传递的时候有什么不同?
- 都是值传递。
- 基本类型的参数传输存储的数据值。
- 引用类型的参数传输存储的地址值。
总结:
总之,不管是基本类型的参数传递还是应用类型的参数传递,其本质都是值传递,只是引用类型传递的是堆内存地址,修改堆内存里面的数据会对原引用类型造成影响。
6.2、方法的参数传递案例
打印整型数组内容
public class MethodTest3 {
public static void main(String[] args) {
// 需求:定义方法,可以打印任意整型数组的内容:[12, 32, 23]
// 4、定义数组,再调用方法
int[] arr = {12, 32, 23};
printArray(arr);
System.out.println("-----------------");
int[] arr2 = {};
printArray(arr2);
System.out.println("-----------------");
int[] arr3 = null;
printArray(arr3);
}
/**
1、定义一个方法:参数:整型数组类型的变量 返回值类型申明:void
*/
public static void printArray(int[] arr){
if(arr != null){
// 2、把数组内容打印出来。
System.out.print("[");
// 3、开始遍历数组中的每个数据
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.print(i == arr.length - 1 ? arr[i] : arr[i] + ", ");
}
System.out.println("]");
}else {
System.out.println("当前数组对象不存在,其地址是:null");
}
}
}
输出结果:
[12, 32, 23]
-----------------
[]
-----------------
当前数组对象不存在,其地址是:null
从数组中查询指定元素的索引
public class MethodTest4 {
public static void main(String[] args) {
// 需求:从整型数组中查询某个数据的索引返回,不存在该数据返回-1
// 3、定义数组,调用方法
int[] arr = {11, 22, 33, 66, 87, 19};
int index = searchIndex(arr, 17);
System.out.println("您查询的数据的索引是:" + index);
}
/**
1、定义一个方法:参数接收数组,要查询的数据,返回值:整型
*/
public static int searchIndex(int[] arr, int data){
// 2、开始找出这个数据的索引
for (int i = 0; i < arr.length; i++) {
if(arr[i] == data){
return i;
}
}
return -1; // 查无此元素!
}
}
输出结果:
您查询的数据的索引是:-1
比较2个数组是否一样
public class MethodTest5 {
public static void main(String[] args) {
// 需求:比较任意2个整型数组的内容是否一样,一样返回true 反之
int[] arr1 = {10, 20, 30};
int[] arr2 = {10, 20, 30};
System.out.println(compare(arr1, arr2));
System.out.println("-------------------");
int[] arr3 = null;
int[] arr4 = {};
System.out.println(compare(arr3, arr4));
}
/**
1、定义一个方法:参数:接收2个整型数组,返回值类型:布尔类型
*/
public static boolean compare(int[] arr1, int[] arr2){
if(arr1 != null && arr2 != null){
// 2、判断2个数组的内容是一样的呢
if(arr1.length == arr2.length){
for (int i = 0; i < arr1.length; i++) {
if(arr1[i] != arr2[i]){
return false;
}
}
return true; // 是一样的!
}else {
return false;
}
}else {
return false;
}
}
}
输出结果:
true
-------------------
false
6.3、方法重载
方法重载应用
public class MethodDemo1 {
public static void main(String[] args) {
// 目标:识别方法重载的形式。并理解其调用流程,最后需要知道使用方法重载的好处。
fire();
fire("岛国");
fire("岛国", 1000);
}
public static void fire(){
fire("米国");
}
public static void fire(String location){
fire(location, 1);
}
public static void fire(String location, int number){
System.out.println("默认发射"+number+"枚武器给"+location+"~~~");
}
}
常见面试题
public class MethodDemo2 {
// 新方法
public static void open() {}
// 重载方法
public static void open(int a) {}
// 重载方法
static void open(int a, int b) {}
// 重载方法
public static void open(double a, int b) {}
// 重载方法
public static void open(int a, double b) {}
// 重复方法
// public void open(int i, double d) { }
// 新方法
public static void OPEN(){ }
}
6.4、return的应用
作用:跳出不合法的方法
代码演示:
public class ReturnDemo {
public static void main(String[] args) {
// 目标:明确return关键字的作用。
System.out.println("main开始。。");
chu(10 , 0);
System.out.println("main结束。。");
}
public static void chu(int a, int b){
if(b == 0){
System.out.println("您输入的数据有问题,除数不能是0!!");
return; // 立即跳出当前方法,并结束当前方法的执行。
}
int c = a / b;
System.out.println("结果是:" + c);
}
}
输出结果:
main开始。。
您输入的数据有问题,除数不能是0!!
main结束。。
6.5、初探static 关键字
Java中,方法可以用static关键字修饰
【非static方法】归属于对象,要先创建对象,而后才可以使用非static方法;
【static方法】归属于类,不需要创建对象就可以被调用。
演示
public class Add {
public int sum(int a, int b){
int c = a + b;
return c;
}
public static int sum2(int a, int b){
int c = a + b;
return c;
}
}
public class Test {
public static void main(String[] args) {
Add add = new Add();
add.sum(10, 5);
Add.sum2(10, 5);
}
}
6.6、补充:Java中 break continue return 的区别
参考链接:https://www.cnblogs.com/514929hgy/p/6915128.html
break
跳出当前循环。但是如果是嵌套循环,则只能跳出当前的这一层循环,只有逐层break才能跳出所有循环。
for (int i = 0; i < 10; i++) {
if (i == 6) {
break;
// 在执行i==6时强制终止循环,i==6不会被执行
}
System.out.println(i);
}
// 输出结果为0 1 2 3 4 5 ;6以后的都不会输出
continue
终止当前循环,但是不跳出循环(在循环中continue后面的语句是不会执行了),继续往下根据循环条件执行循环。
for (int i = 0; i < 10; i++) {
if (i == 6) {
continue;
// i==6不会被执行,而是被中断了
}
System.out.println(i);
}
// 输出结果为0 1 2 3 4 5 7 8 9;只有6没有输出
return
- return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行。
- return 返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致。
- return 后面也可以不带参数,不带参数就是返回空,其实主要目的就是用于想中断函数执行,返回调用函数处。
特别注意:返回值为void的方法,从某个判断中跳出,必须用return.
7、Java 基础练习
7.1、买飞机票
import java.util.Scanner;
/**
需求:机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。
按照如下规则计算机票价格:旺季(5-10月)头等舱9折,经济舱8.5折,淡季(11月到来年4月)头等舱7折,经济舱6.5折。
*/
public class Test1 {
public static void main(String[] args) {
// 3、录入购买信息,调用方法得到最终结果
Scanner sc = new Scanner(System.in);
System.out.println("机票原价:");
double price = sc.nextDouble();
System.out.println("月份:");
int month = sc.nextInt();
System.out.println("仓位类型(头等舱、经济舱):");
String type = sc.next();
double rs = calc(price, month, type);
System.out.println("您当前购买机票的价格是:" + rs);
}
/**
1、定义一个方法:形参(原价、月份、头等舱经济舱) 返回值类型申明:double
*/
public static double calc(double money, int month, String type){
// 2、判断月份是淡季还是旺季
if(month >= 5 && month <= 10){
// 旺季
switch (type){
case "经济舱":
money *= 0.85;
break;
case "头等舱":
money *= 0.9;
break;
default:
System.out.println("您输入的仓位不正确~~");
money = -1; // 当前无法计算价格了!
}
}else if(month == 11 || month == 12 || month >= 1 && month <= 4){
switch (type){
case "经济舱":
money *= 0.65;
break;
case "头等舱":
money *= 0.7;
break;
default:
System.out.println("您输入的仓位不正确~~");
money = -1; // 当前无法计算价格了!
}
}else {
System.out.println("月份有问题");
money = -1;
}
return money;
}
}
7.2、找素数
/**
需求:找出101-200之间的素数输出:
素数是什么:如果除了1和它本身以外,不能被其他正整数整除,就叫素数。
*/
public class Test2 {
public static void main(String[] args) {
// 1、定义一个循环,找到101-200之间的全部数据
for (int i = 101; i <= 200 ; i++) {
// i = 101 102 103 ... 199 200
// 信号位:标记
boolean flag = true; // 一开始认为当前数据是素数。
// 2、判断当前遍历的这个数据是否是素数
for (int j = 2; j < i / 2; j++) {
if(i % j == 0){
flag = false; // 假设失败了,i不是素数
break; // 没有必要继续判定下去了!
}
}
// 3、根据判定的结果选择是否输出这个数据,是素数则输出
if(flag){
System.out.print(i + "\t");
}
}
}
}
输出结果:
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
7.3、开发验证码
/**
需求:定义方法实现随机产生一个5位的验证码,每位可能是数字、大写字母、小写字母。
*/
public class Test3 {
public static void main(String[] args) {
// 4、调用获取验证码的方法得到一个随机的验证码
String code = createCode(5);
System.out.println("随机验证码:" + code);
}
/**
1、定义一个方法返回一个随机验证码:是否需要返回值类型申明?String 是否需要申明形参:int n
*/
public static String createCode(int n){
// 3、定义一个字符串变量记录生成的随机字符
String code = "";
Random r = new Random();
// 2、定义一个for循环,循环n次,依次生成随机字符
for (int i = 0; i < n; i++) {
// i = 0 1 2 3 4
// 3、生成一个随机字符:英文大写 小写 数字 (0 1 2)
int type = r.nextInt(3); // 0 1 2
switch (type){
case 0:
// 大写字符(A 65 - Z 65+25) (0 - 25) + 65
char ch = (char) (r.nextInt(26) + 65);
code += ch;
break;
case 1:
// 小写字符(a 97 - z 97+25) (0 - 25) + 97
char ch1 = (char) (r.nextInt(26) + 97);
code += ch1;
break;
case 2:
// 数字字符
code += r.nextInt(10); // 0 - 9
break;
}
}
return code;
}
}
输出结果:
随机验证码:X2DXD
7.4、数组元素复制
/**
需求:把一个数组中的元素复制到另一个新数组中去。
*/
public class Test4 {
public static void main(String[] args) {
int[] arr1 = {11, 22, 33, 44};
// int[] arr2 = arr1; // 没有完成了数组复制。
int[] arr2 = new int[arr1.length];
copy(arr1 , arr2);
printArray(arr1);
printArray(arr2);
}
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("]");
}
public static void copy(int[] arr1, int[] arr2){
// 正式完成元素的复制
for (int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
}
}
输出结果:
[11, 22, 33, 44]
[11, 22, 33, 44]
7.5、评委打分案例
import java.util.Scanner;
/**
需求:在唱歌比赛中,有6名评委给选手打分,分数范围是[0 - 100]之间的整数。
选手的最后得分为:去掉最高分、最低分后的4个评委的平均分,请完成上述过程并计算出选手的得分。
*/
public class Test5 {
public static void main(String[] args) {
// 1、定义一个动态初始化的数组,用于后期录入6个评委的分数
int[] scores = new int[6];
// 2、录入6个评委的分数
Scanner sc = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.println("请您输入第" + (i + 1) +"个评委的打分:");
int score = sc.nextInt();
// 3、把这个分数存入到数组的对应位置处
scores[i] = score;
}
// 3、遍历数组中的每个数据,找出最大值 最小值 总分
// int max = scores[0] , min = scores[0] , sum = 0;
int max = scores[0] ;
int min = scores[0] ;
int sum = 0;
for (int i = 0; i < scores.length; i++) {
if(scores[i] > max){
// 替换最大值变量存储的数据
max = scores[i];
}
if(scores[i] < min){
// 替换最小值变量存储的数据
min = scores[i];
}
// 统计总分
sum += scores[i];
}
System.out.println("最高分是:" + max);
System.out.println("最低分是:" + min);
// 4、统计平均分即可
double result = (sum - max - min) * 1.0 / (scores.length - 2);
System.out.println("选手最终得分是:" + result);
}
}
7.6、数字加密
/**
需求:某系统的数字密码,比如1983,采用加密方式进行传输,规则如下:先得到每位数,
然后每位数都加上5再对10求余,最后将所有数字反转,得到一串新数。
*/
public class Test6 {
public static void main(String[] args) {
// 1、定义一个数组存储需要加密的数据
int[] arr = new int[]{1, 9, 8, 3};
// 2、遍历数组中的每个数据,按照规则进行修改
for (int i = 0; i < arr.length; i++) {
arr[i] = (arr[i] + 5) % 10;
}
// 3、把数组中的元素进行反转操作。
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
// 交换 i 和 j位置处的值,即可反转
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
// 4、遍历数组中的每个元素输出即可
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
}
}
输出结果:
8346
备注
其实加密过程就是解密过程,去感受数学的魅力吧。
7.7、模拟双色球
import java.util.Random;
import java.util.Scanner;
/**
需求:双色球模拟
*/
public class Test7 {
public static void main(String[] args) {
// 1、随机6个红球号码(1-33,不能重复),随机一个蓝球号码(1-16),可以采用数组装起来作为中奖号码
int[] luckNumbers = createLuckNumber();
// printArray(luckNumbers);
// 2、录入用户选中的号码
int[] userNumbers = userInputNumbers();
// 3、判断中奖情况
judge(luckNumbers, userNumbers);
}
public static void judge(int[] luckNumbers, int[] userNumbers ){
// 判断是否中奖了。
// luckNumbers = [12, 23, 8, 16, 15, 32, 9]
// userNumbers = [23, 13, 18, 6, 8, 33, 10]
// 1、定义2个变量分别存储红球命中的个数,以及蓝球命中的个数。
int redHitNumbers = 0;
int blueHitNumbers = 0;
// 2、判断红球命中了几个,开始统计
for (int i = 0; i < userNumbers.length - 1; i++) {
for (int j = 0; j < luckNumbers.length - 1; j++) {
// 每次找到了相等了,意味着当前号码命中了
if(userNumbers[i] == luckNumbers[j]){
redHitNumbers ++ ;
break;
}
}
}
// 蓝球号码是否命中了
blueHitNumbers = luckNumbers[6] == userNumbers[6] ? 1 : 0;
System.out.println("中奖号码是:" );
printArray(luckNumbers);
System.out.println("您投注号码是:" );
printArray(userNumbers);
System.out.println("您命中了几个红球:" + redHitNumbers);
System.out.println("您是否命中蓝球:" + ( blueHitNumbers == 1 ? "是": "否" ) );
// 判断中奖情况了
if(blueHitNumbers == 1 && redHitNumbers < 3){
System.out.println("恭喜您,中了5元小奖!");
}else if(blueHitNumbers == 1 && redHitNumbers == 3
|| blueHitNumbers == 0 && redHitNumbers == 4){
System.out.println("恭喜您,中了10元小奖!");
}else if(blueHitNumbers == 1 && redHitNumbers == 4
|| blueHitNumbers == 0 && redHitNumbers == 5){
System.out.println("恭喜您,中了200元!");
}else if(blueHitNumbers == 1 && redHitNumbers == 5){
System.out.println("恭喜您,中了3000元大奖!");
}else if(blueHitNumbers == 0 && redHitNumbers == 6){
System.out.println("恭喜您,中了500万超级大奖!");
}else if(blueHitNumbers == 1 && redHitNumbers == 6){
System.out.println("恭喜您,中了1000万巨奖!可以开始享受人生,诗和远方!!");
}else {
System.out.println("感谢您为福利事业做出的突出贡献!!");
}
}
public static int[] userInputNumbers(){
// a、动态初始化一个数组,长度为7
int[] numbers = new int[7];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < numbers.length - 1; i++) {
System.out.println("请您输入第"+(i + 1)+"个红球号码(1-33、不重复):");
int data = sc.nextInt();
numbers[i] = data;
}
// b、录入一个蓝球号码
System.out.println("请您输入一个蓝球号码(1-16):");
int data = sc.nextInt();
numbers[numbers.length - 1] = data;
return numbers;
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static int[] createLuckNumber(){
// a、定义一个动态初始化的数组,存储7个数字
int[] numbers = new int[7]; // [12, 23, 0, 0, 0, 0, | 0]
// i
// b、遍历数组,为每个位置生成对应的号码。(注意:遍历前6个位置,生成6个不重复的红球号码,范围是1-33)
Random r = new Random();
for (int i = 0; i < numbers.length - 1; i++) {
// 为当前位置找出一个不重复的1-33之间的数字
while (true) {
int data = r.nextInt(33) + 1; // 1-33 ====> (0-32) + 1
// c、注意:必须判断当前随机的这个号码之前是否出现过,出现过要重新随机一个,直到不重复为止,才可以存入数组中去。
// 定义一个flag变量,默认认为data是没有重复的
boolean flag = true;
for (int j = 0; j < i; j++) {
if(numbers[j] == data) {
// data当前这个数据之前出现过,不能用
flag = false;
break;
}
}
if(flag) {
// data这个数据之前没有出现过,可以使用了
numbers[i] = data;
break;
}
}
}
// d、为第7个位置生成一个1-16的号码作为蓝球号码
numbers[numbers.length - 1] = r.nextInt(16) + 1;
return numbers;
}
}