Java基础1(数组)

Java基础1(数组)

一、Java语言概述

Java软件开发介绍

常用DOS命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8apwxCoX-1635843764665)(Java.assets/image-20210517210042760.png)]

cd -change directory

rd -remove directory

del -delete

dir -directory

md -make directory

c盘进入D盘 d:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4A4fARY-1635843764670)(Java.assets/image-20210518211629029.png)]

常用指令 https://baike.baidu.com/item/dos/6672671?fr=aladdin

Java语言概述

Java技术体系平台

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jclzfCEG-1635843764672)(Java.assets/image-20210519101752558.png)]

Java在各领域的应用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NMLaR9fA-1635843764674)(Java.assets/image-20210519101825085.png)]

Java语言运行机制及运行过程

Java语言的特点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjITkzKr-1635843764676)(Java.assets/image-20210517180949548.png)]

Java两种核心机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxVJZIsD-1635843764676)(Java.assets/image-20210517181250101.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5gXcJWlr-1635843764677)(Java.assets/image-20210517181327772.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85Vtnmtz-1635843764678)(Java.assets/image-20210517181355530.png)]

java语言的环境搭建

JDK、JRE、JVM 的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2wx2CvP4-1635843764679)(Java.assets/image-20210514204141099.png)]

image-20210514204848674

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Ln6mn1x-1635843764680)(Java.assets/image-20210517182146826.png)]

Java语言环境的搭建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMqo1pgb-1635843764681)(Java.assets/image-20210517211554351.png)]

开发体验-HelloWorld

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IrzdU3a5-1635843764682)(Java.assets/image-20210518110253454.png)]

javac FamilyAccount.java // 此时不区分大小写

java FamilyAccount		// 此时区分大小写

关于Java里边文件名大小写

字节码名=类名,字节码文件对应类,函数里边有几个类就会生成几个字节码文件。

windows系统不区分大小写

Java代码严格区分大小写

故javac编译的时候 搜索文件夹里边文件名的时候不区分大小写,但用java运行class文件的时候要区分大小写

注释

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6rTtFzkz-1635843764683)(Java.assets/image-20210518163819864.png)]

Java API文档

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZLsALx6q-1635843764684)(Java.assets/image-20210518170854650.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2jeNaMMb-1635843764685)(Java.assets/image-20210519114841412.png)]

二、Java基本语法

关键字和保留字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nU6PjIwd-1635843764686)(Java.assets/image-20210520092714695.png)]

image-20210817171227751

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwADwmbx-1635843764687)(Java.assets/image-20210520092732155.png)]

标识符(可以自己取名字的)

规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8stIeJS-1635843764688)(Java.assets/image-20210519151102722.png)]

规范

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdBEcLAd-1635843764689)(Java.assets/image-20210519151128836.png)]

两个简单的输出语句


1. 参数有区别:

System.out.println() 可以不写参数

System.out.print(参数) 参数不能为空.必须有

2.效果有区别

println :会在输出完信息后进行换行,产生一个新行
print: 不会产生新行
3.println更简洁, print更灵活
print可以后面跟"\n"来达到和println一样的效果
也可以跟"\t" 制表符,.
————————————————

原文链接:https://blog.csdn.net/weixin_44720673/article/details/88791884

变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-APbPo8VU-1635843764689)(Java.assets/image-20210519165140783.png)]

布尔类型

Java中的真,假只能由布尔型(boolean)的true和false来表示,不对应任何数值.

基本数据类型转换

自动类型转换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-132HR5wv-1635843764690)(Java.assets/image-20210819163210265.png)]

Java里边整型常量默认为int型,浮点型常量默认为

强制类型转换
变量运算规则的两种特殊情况

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q6HJP7qZ-1635843764691)(Java.assets/image-20210519180217183.png)]

​ 数据123213后不加L时,默认是int型再转换成long型。这种情况下,过大的整数会出现编译失败。

进制

见ppt

运算符

算术运算符

自增自减运算符
short s1 = 10;
//s1 = s1 + 1;//编译失败  常量默认是int型,s1运算时候会自动转换为int型
//s1 = (short)(s1 + 1);//正确的
s1++;//自增1不会改变本身变量的数据类型
System.out.println(s1);

	//问题:
	byte bb1 =127;
	bb1++;
	System.out.println("bb1 = " + bb1);
结果: bb1 = -128
//练习1
int i = 1;
i *= 0.1;
System.out.println(i);//0
i++;
System.out.println(i);//1
连接符 ( + )

赋值运算符

short s1 = 10;
//s1 = s1 + 2;//编译失败 常量默认是int型,s1运算时候会自动转换为int型
s1 += 2;//结论:不会改变变量本身的数据类型
System.out.println(s1);
tips
//开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10;)
		//方式一:num = num + 2;
		//方式二:num += 2; (推荐) 不会改变本身数据类型
		
//开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10;)
		//方式一:num = num + 1;
		//方式二:num += 1; 
		//方式三:num++; (推荐)

逻辑运算符

//说明:
//1.逻辑运算符操作的都是boolean类型的变量	

		//区分& 与 &&
		//相同点1:& 与  && 的运算结果相同
		//相同点2:当符号左边是true时,二者都会执行符号右边的运算
		//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
		//开发中,推荐使用&&
		boolean b1 = true;
		b1 = false;
		int num1 = 10;
		if(b1 & (num1++ > 0)){
			System.out.println("我现在在北京");
		}else{
			System.out.println("我现在在南京");
		}

		System.out.println("num1 = " + num1);
		

		boolean b2 = true;
		b2 = false;
		int num2 = 10;
		if(b2 && (num2++ > 0)){
			System.out.println("我现在在北京");
		}else{
			System.out.println("我现在在南京");
		}

		System.out.println("num2 = " + num2);
		// 区分:| 与 || 
		//相同点1:| 与  || 的运算结果相同
		//相同点2:当符号左边是false时,二者都会执行符号右边的运算
		//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
		//开发中,推荐使用||

位运算符

		//练习:交换两个变量的值
		int num1 = 10;
		int num2 = 20;
		System.out.println("num1 = " + num1 + ",num2 = " + num2);

		//方式一:定义临时变量的方式
		//推荐的方式
		int temp = num1;
		num1 = num2;
		num2 = temp;

		//方式二:好处:不用定义临时变量  
		//弊端:① 相加操作可能超出存储范围 ② 有局限性:只能适用于数值类型
		//num1 = num1 + num2;
		//num2 = num1 - num2;
		//num1 = num1 - num2;

		//方式三:使用位运算符
		//有局限性:只能适用于数值类型
		//num1 = num1 ^ num2;
		//num2 = num1 ^ num2;
		//num1 = num1 ^ num2;

		System.out.println("num1 = " + num1 + ",num2 = " + num2);

三元运算符

三元运算符和if-else的使用说明

 /*
运算符之六:三元运算符
1.结构:(条件表达式)? 表达式1 : 表达式2
2. 说明
① 条件表达式的结果为boolean类型
② 根据条件表达式真或假,决定执行表达式1,还是表达式2.
  如果表达式为true,则执行表达式1。
  如果表达式为false,则执行表达式2。
③ 表达式1 和表达式2要求是一致的。
④ 三元运算符可以嵌套使用

3. 
凡是可以使用三元运算符的地方,都可以改写为if-else
反之,不成立。

4. 如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。
*/

程序流程控制

顺序结构

分支结构

if-else

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2OTDcVor-1635843764692)(Java.assets/image-20210524111456158.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0P84BWg-1635843764693)(Java.assets/image-20210524111511217.png)]

Scanner类语法 (键盘输入)
/*
如何从键盘获取不同类型的变量:需要使用Scanner类

具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量

注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
//1.导包:import java.util.Scanner;
import java.util.Scanner;

class ScannerTest{
	
	public static void main(String[] args){
		//2.Scanner的实例化
		Scanner scan = new Scanner(System.in);
		
		//3.调用Scanner类的相关方法
		System.out.println("请输入你的姓名:");
		String name = scan.next(); //读取字符串
		System.out.println(name);

		System.out.println("请输入你的芳龄:");
		int age = scan.nextInt(); //读取数字
		System.out.println(age);
    }
}
math类(随机数的产生)
//课后练习4:如何获取一个随机数:10 - 99
int value = (int)(Math.random() * 90 + 10);
// [0.0,1.0) --> [0.0,90.0) --->[10.0, 100.0) -->[10,99]
System.out.println(value);
//Math.random()  : [0.0,1.0)
//公式:获取[a,b]范围内的随机数: 
//(int)(Math.random() * (b - a + 1) + a)    
switch-case
/*
分支结构之二:switch-case

1.格式
switch(表达式){
case 常量1:
	执行语句1;
	//break;

case 常量2:
	执行语句2;
	//break;

...

default:
	执行语句n;
	//break;

}

2.说明:
① 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。
  当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构
  末尾结束为止。

② break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构

③ switch结构中的表达式,只能是如下的6种数据类型之一:
   byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)

④ case 之后只能声明常量。不能声明范围。

⑤ break关键字是可选的。

⑥ default:相当于if-else结构中的else.  
  default结构是可选的,而且位置是灵活的。
*/
if-else和switch-case的使用说明
/*说明:
1. 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
2. 我们写分支结构时,当发现既可以使用switch-case,(同时,switch中表达式的取值情况不太多),
  又可以使用if-else时,我们优先选择使用switch-case。原因:switch-case执行效率稍高。
*/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYT8x7P7-1635843764694)(Java.assets/image-20210524152746523.png)]

两边执行效率稍高一些

循环结构

For循环
关于变量未赋值导致编译不过的一个问题
class ReviewTest{

	public static void main(String[] args){
		int sum ;				//此处未赋值会导致编译过不了,因为编译器会判定For循环不一定能进入,sum不一定会被赋值。
        						//若去掉For循环,只留下if-elss可以通过编译。 p
		for(int i = 1;i <= 100;i++){
			if(4 % 2 == 0){
				System.out.println(i);
				sum = 1;
			}else{
				sum = 2;
			}
		}
		System.out.println(sum);
	}

}
while循环
do-while循环
嵌套循环

九九乘法表

10000以内所有质数

//10000以内的质数(素数)

class PrimeNumberTest {
	public static void main(String[] args) {
		
		int flag = 0;
		int count = 0;//记录质数的个数。
		long start = System.currentTimeMillis();
		for(int i = 2;i <= 100000;i++){
			      		  //优化二:对本身质数的自然数的优化。
			for(int j = 2;j <= Math.sqrt(i);j++){
				if(i % j == 0 && i != j){
					flag = 1;
					break;//优化一: 只对本身非质数的自然数的优化。
				}
			}
			if(flag == 0)
				//System.out.println(i);
				count++;
			flag = 0;// 重置flag
		}

		long end = System.currentTimeMillis();


		System.out.println("个数为:" + count);
		System.out.println("所花费的时间为:" + (end - start)); // 19825 - 2542
	}
}

break和continue和return关键字

1、基本功能

/*
break和continue关键字的使用
				使用范围			循环中使用的作用(不同点)		相同点
break:			switch-case			
				循环结构中			结束当前循环					关键字后面不能声明执行语句									

continue:		循环结构中			结束当次循环					关键字后面不能声明执行语句
								  (之后执行i++)


*/

2、带标签的break和continue

class BreakContinueTest {
	public static void main(String[] args) {

		for(int i = 1;i <= 10;i++){
		
			if(i % 4 == 0){
				break;//输出123
				//continue;//输出123567910
				//System.out.println("今晚迪丽热巴要约我!!!");
			}
			System.out.print(i);
		}

		System.out.println("\n");
		//******************************
		
		label:for(int i = 1;i <= 4;i++){
		
			for(int j = 1;j <= 10;j++){
				
				if(j % 4 == 0){
					//break;//默认跳出包裹此关键字最近的一层循环。
					//continue; //结束包裹此关键字最近的当次循环

					//break label;//结束指定标识的一层循环结构
					continue label;//结束指定标识的一层循环结构当次循环
				}
				
				System.out.print(j);
			}
			
			System.out.println();
		}
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htrBe0hs-1635843764695)(Java.assets/image-20210818170811746.png)]

Eclipse的安装与配置

Eclipse的使用配置.pdf

数组

重点掌握一维数组、二维数组的六个基本点。

数组的概述

/*
 * 一、数组的概述
 * 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,
 * 并通过编号的方式对这些数据进行统一管理。
 * 
 * 2.数组相关的概念:
 * >数组名
 * >元素
 * >角标、下标、索引
 * >数组的长度:元素的个数
 * 
 * 3.数组的特点:
 * 1)数组是有序排列的
 * 2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
 * 3)创建数组对象会在内存中开辟一整块连续的空间
 * 4)数组的长度一旦确定,就不能修改。
 * 
 * 4. 数组的分类:
 *   ① 按照维数:一维数组、二维数组、。。。
 *   ② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
 * 
 * 5. 一维数组的使用
 *   ① 一维数组的声明和初始化
 *   ② 如何调用数组的指定位置的元素
 *   ③ 如何获取数组的长度
 *   ④ 如何遍历数组
 *   ⑤ 数组元素的默认初始化值 :见ArrayTest1.java
 *   ⑥ 数组的内存解析 :见ArrayTest1.java
 */

数组的使用

一维数组

1、一维数组的使用
/* 5. 一维数组的使用
 *   ① 一维数组的声明和初始化
 *   ② 如何调用数组的指定位置的元素
 *   ③ 如何获取数组的长度
 *   ④ 如何遍历数组
 *   ⑤ 数组元素的默认初始化值 :见ArrayTest1.java
 *   ⑥ 数组的内存解析 :见ArrayTest1.java
 */

ArrayTest.java

package com.atguigu.java;

public class ArrayTest {
	
	public static void main(String[] args) {
		
		//1. 一维数组的声明和初始化
		int num;//声明
		num = 10;//初始化
		int id = 1001;//声明 + 初始化
		
		int[] ids;//声明
		//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
		ids = new int[]{1001,1002,1003,1004};
		//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
		String[] names = new String[5];
		
				//Sum: 前边都是空的,后边指定长度或者元素。
		//错误的写法:
//		int[] arr1 = new int[];既没有赋值也没有指定长度
//		int[5] arr2 = new int[5];前边中括号永远是空的
//		int[] arr3 = new int[3]{1,2,3}; 静态和动态合在一块儿了
		
		//也是正确的写法:
		int[] arr4 = {1,2,3,4,5};//类型推断
		
		//Sum总结:数组一旦初始化完成,其长度就确定了。
		
		//2.如何调用数组的指定位置的元素:通过角标的方式调用。
		//数组的角标(或索引)从0开始的,到数组的长度-1结束。
		names[0] = "王铭";
		names[1] = "王赫";
		names[2] = "张学良";
		names[3] = "孙居龙";
		names[4] = "王宏志";//charAt(0)
//		names[5] = "周扬"; 数组越界
		
		//3.如何获取数组的长度。
		//属性:length
		System.out.println(names.length);//5
		System.out.println(ids.length);//4
		
		//4.如何遍历数组
		/*System.out.println(names[0]);
		System.out.println(names[1]);
		System.out.println(names[2]);
		System.out.println(names[3]);
		System.out.println(names[4]);*/
		
		for(int i = 0;i < names.length;i++){
			System.out.println(names[i]);
		}
		
		
	}

}


1、类型推断:数组的静态初始化和数组元素的赋值操作同时进行时。动态初始化时不能省。

一维数组: int[] arr4 =new int[ ]{1,2,3,4,5};

​ 可以写成 int[] arr4 = {1,2,3,4,5};

二维数组:int[] arr5 [] = new int[ ] [ ]{{1,2,3},{4,5},{6,7,8}};

​ 可以写成 int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};

2、中括号和变量名的位置不分前后。数据类型永远在最前边。

一维数组:可以写int[ ] arr4 或者int arr4[] 。一般采用前者。

二维数组:int[][] [ ] [ ]arr 可以写成int[] arr[]或者 int arr5[ ] [ ]

3、数组一旦初始化完成,其长度就确定了。将静态和动态杂糅在一起也是错的。

[][]

ArrayTest1.java

package com.atguigu.java;
/*
 * ⑤ 数组元素的默认初始化值
 * 		> 数组元素是整型:0
 * 		> 数组元素是浮点型:0.0
 * 		> 数组元素是char型:0或'\u0000',而非'0'
 * 		> 数组元素是boolean型:false
 * 
 * 		> 数组元素是引用数据类型:null
 *  
 *  ⑥ 数组的内存解析
 */
public class ArrayTest1 {
	
	public static void main(String[] args) {
		//5.数组元素的默认初始化值
		int[] arr = new int[4];
		for(int i = 0;i < arr.length;i++){
			System.out.println(arr[i]);
		}
		System.out.println("**********");
		
		short[] arr1 = new short[4];
		for(int i = 0;i < arr1.length;i++){
			System.out.println(arr1[i]);
		}
		System.out.println("**********");
		float[] arr2 = new float[5];
		for(int i = 0;i < arr2.length;i++){
			System.out.println(arr2[i]);
		}
		
		System.out.println("**********");
		char[] arr3 = new char[4];
		for(int i = 0;i < arr3.length;i++){
			System.out.println("----" + arr3[i] + "****");
		}
		
		if(arr3[0] == 0){
			System.out.println("你好!");
		}
		
		System.out.println("**********");
		boolean[] arr4 = new boolean[5];
		System.out.println(arr4[0]);
		
		System.out.println("**********");
		String[] arr5 = new String[5];
		System.out.println(arr5[0]);
		if(arr5[0] == null){
			System.out.println("北京天气不错!");
		}
	}

}

2、一维数组的内存简化结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JZpw0OOf-1635843764696)(Java.assets/image-20211025212600270.png)]

1、栈(stack)中保存局部变量,方法中定义的变量都是局部变量。(比如main方法)

2、堆(heap)中一般保存new出来的变量,如数组、对象

3、字符串常量池一般保存string类

4、静态域存放static类

一维数组的内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0fAppDD-1635843764697)(Java.assets/image-20211025214156768.png)]

1、堆中new出来的数据一开始都有默认值,之后对其进行初始化。

2、变量arr1被指定到堆中新的结构之后,arr1变量之前保存的地址值所在的结构会在某一时间被系统回收。(垃圾回收机制)

3、执行完main方法之后,main方法中定义的所有变量都出栈释放,这些变量所指向的结构所占用的内存也将被系统回收。

3、一维数组练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k0kF2HGQ-1635843764698)(Java.assets/image-20211026183603658.png)]

/*
1、快速导包:点击Scanner类名处的错误提示或者 快捷键 ctrl+shift+o
2、alt+up/down 代码上下移动
3、ctrl+shift+f 调整代码格式
4、ctrl+i 调整代码缩进
5、alt+/ 智能补全
6、ctrl+1 智能补全
7、ctrl+shift+r批量修改同名变量名
*/
/*
 * 2. 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
		成绩>=最高分-10    等级为’A’   
		成绩>=最高分-20    等级为’B’
		成绩>=最高分-30    等级为’C’   
		其余                               等级为’D’
		
		提示:先读入学生人数,根据人数创建int数组,存放学生成绩。

 * 
 */


package com.atguigu.exer;

import java.util.Scanner; 

public class ArrayDemo1 {
	public static void main(String[] args) {
		//1.使用Scanner,读取学生个数
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入学生人数:");
		int number = scanner.nextInt();
		
		//2.创建数组,存储学生成绩:动态初始化
		int[] scores = new int[number];
		//3.给数组中的元素赋值
		System.out.println("请输入" + number + "个学生成绩:");
		int maxScore = 0;
		for(int i = 0;i < scores.length;i++){
			scores[i] = scanner.nextInt();
			//4.获取数组中的元素的最大值:最高分
			if(maxScore < scores[i]){
				maxScore = scores[i];
			}
		}
//		for(int i = 0;i < scores.length;i++){
//			if(maxScore < scores[i]){
//				maxScore = scores[i];
//			}
//		}
		
		//5.根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
		char level;
		for(int i = 0;i < scores.length;i++){
			if(maxScore - scores[i] <= 10){
				level = 'A';
			}else if(maxScore - scores[i] <= 20){
				level = 'B';
			}else if(maxScore - scores[i] <= 30){
				level = 'C';
			}else{
				level = 'D';
			}
			
			System.out.println("student " + i + 
					" score is " + scores[i] + ",grade is " + level);
		}
		
	}
}

二维数组

1、二维数组的使用part1
/*
 * 二维数组的使用
 * 
 * 1.理解:
 * 对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
 * 其实,从数组底层的运行机制来看,其实没有多维数组。
 * 
 * 2. 二维数组的使用:
 *   ① 二维数组的声明和初始化
 *   ② 如何调用数组的指定位置的元素
 *   ③ 如何获取数组的长度
 *   ④ 如何遍历数组
 *   ⑤ 数组元素的默认初始化值 :见 ArrayTest3.java
 *   ⑥ 数组的内存解析 :见 ArrayTest3.java
 * 
 * 
 */


ArrayTest2.java

package com.atguigu.java;


public class ArrayTest2 {
	public static void main(String[] args) {
		//1.二维数组的声明和初始化
		int[] arr = new int[]{1,2,3};//一维数组
		//静态初始化
		int[][] arr1 = new int[][]{{1,2,3},{4,5,6},{6,7,8}};
		//动态初始化1
		String[][] arr2 = new String[3][2];
		//动态初始化2
		String[][] arr3 = new String[3][];
		//错误的情况 
//		String[][] arr4 = new String[][4]; 第一维的数字不能为空
//		String[4][3] arr5 = new String[][];前边括号必须为空
//		int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
			//长度和赋值只能存在一个,不能同时存在					
		//也是正确的写法:
		int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
		int[] arr5[] = {{1,2,3},{4,5},{6,7,8}}; //类型推断
		
		//2.如何调用数组的指定位置的元素
		System.out.println(arr1[0][1]);//2
		System.out.println(arr2[1][1]);//null
		
		arr3[1] = new String[4];
		System.out.println(arr3[1][0]);
		
		//3.获取数组的长度
		System.out.println(arr4.length);//3
		System.out.println(arr4[0].length);//3
		System.out.println(arr4[1].length);//4
		
		//4.如何遍历二维数组
		for(int i = 0;i < arr4.length;i++){
			
			for(int j = 0;j < arr4[i].length;j++){
				System.out.print(arr4[i][j] + "  ");
			}
			System.out.println();
		}
		
	}
}

1、二维数组动态初始化时,第二维的数字可以留空。

2、二维数组的使用part2
/*
 * 二维数组的使用:
 * 	规定:二维数组分为外层数组的元素,内层数组的元素
 * 		int[][] arr = new int[4][3];
 * 		外层元素:arr[0],arr[1]等
 * 		内层元素:arr[0][0],arr[1][2]等
 * 
 *   ⑤ 数组元素的默认初始化值 
 *   针对于初始化方式一:比如:int[][] arr = new int[4][3];
 *      外层元素的初始化值为:地址值
 *      内层元素的初始化值为:与一维数组初始化情况相同
 *      
 *   针对于初始化方式二:比如:int[][] arr = new int[4][];
 *   	外层元素的初始化值为:null
 *      内层元素的初始化值为:不能调用,否则报错。
 *   
 *   ⑥ 数组的内存解析 
 * 
 */

ArrayTest3.java

package com.atguigu.java;


public class ArrayTest3 {
	public static void main(String[] args) {
		
		int[][] arr = new int[4][3];
		System.out.println(arr[0]);//[I@15db9742 是一个一维地址值
		System.out.println(arr[0][0]);//0 
		
//		System.out.println(arr);//[[I@6d06d69c 是一个二维地址值
		
		System.out.println("*****************");
		float[][] arr1 = new float[4][3];
		System.out.println(arr1[0]);//地址值
		System.out.println(arr1[0][0]);//0.0
		
		System.out.println("*****************");
		
		String[][] arr2 = new String[4][2];
		System.out.println(arr2[1]);//地址值
		System.out.println(arr2[1][1]);//null
		
		System.out.println("*****************");
		double[][] arr3 = new double[4][];
		System.out.println(arr3[1]);//null
//		System.out.println(arr3[1][0]);//报错
		
	}
}
3、二维数组的内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5oWb5VtV-1635843764699)(Java.assets/image-20211026123617260.png)]

1、数组也属于引用类型,引用类型的变量只有两种值,null 或者 地址值

4、二维数组练习
Exer1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIWN7Pi7-1635843764700)(Java.assets/image-20211027104323307.png)]

//1、老师的答案,静态数组
//2、自己写的,动态数组
//此处静态数组更好,因为二维的数量不是固定的

package com.atguigu.exer;

public class ArrayExer1 {
	
	public static void main(String[] args) {
		int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
		
		int sum = 0;//记录总和
		for(int i = 0;i < arr.length;i++){
			for(int j = 0;j < arr[i].length;j++){
				sum += arr[i][j];
			}
		}
		
		System.out.println("总和为:" + sum);
	}
	
}

//----------------------------------------------------------------


package com.atguigu.exer;

import java.util.Scanner;

public class ArrayExer1 {
	public static void main(String[] args) {
		//1、定义一个sum变量来存储元素的和
		int sum = 0;
		//2、创建动态数组,在输入数组数值的同时对sum进行累加
				//此处用静态初始化更好,因为二维的个数不是全都一样的
		int[][] arr = new int[3][4];
		Scanner scan = new Scanner(System.in);
		for(int i = 0;i < arr.length;i++){
			for(int j = 0;j < arr[i].length;j++){
				arr[i][j] = scan.nextInt();
				sum += arr[i][j];
			}
		}
		System.out.println(sum);
	}
}
Exer2
声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:
			//此处x是一维数组,y是二维数组
x[0] = y; //no; 元素≠二维地址值
y[0] = x; //yes;
y[0][0] = x; //no;元素≠一维地址值
x[0][0] = y; //no;前边不存在
y[0][0] = x[0]; //yes
x = y; //no;一维地址值≠二维地址值

   提示:
一维数组:int[] x 或者int x[]
二维数组:int[][] y 或者 int[] y[] 或者 int y[][]

1、一维数组名和二维数组名之间也不能相互赋值。二维不能赋值给一维,虽然都是地址值,但地址值前还有变量的类型。如二维地址打印出来前边还会显示"[["

2、可以赋值的两种情况,类型一样或者可以自动类型提升。

Exer3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tZOwf1qa-1635843764701)(Java.assets/image-20211027111036224.png)]

其实就是(a+b)n 开出来次方之后的系数值。


//前老师后自己
//1.学会写注释的格式,要有层次感,看起来更清晰直观
//2.本质就是初始化二维数组,并按照特定要求赋值



package com.atguigu.exer;

public class YangHuiTest {
	
	public static void main(String[] args) {
		//1.声明并初始化二维数组
		int[][] yangHui = new int[10][];
		
		//2.给数组的元素赋值
		for(int i = 0;i < yangHui.length;i++){
			yangHui[i] = new int[i + 1];
			
			//2.1 给首末元素赋值
			yangHui[i][0] = yangHui[i][i] = 1;//连续赋值
			//2.2 给每行的非首末元素赋值
			//if(i > 1){
			for(int j = 1;j < yangHui[i].length - 1;j++){
				yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
			}
			//}
		}
				
		//3.遍历二维数组
		for(int i = 0;i < yangHui.length;i++){
			for(int j = 0;j < yangHui[i].length;j++){
				System.out.print(yangHui[i][j] + "  ");
			}
			System.out.println();
		}	
	}
}

//-------------------------------------------------------------



package com.atguigu.exer;

public class YangHuiTest {
	
	public static void main(String[] args) {
		//1.先动态初试化一个二维数组,一维定10二维不定。二维的维数放到循环中确定
		int[][] yanghui  = new int[10][]; //一共有10行
		
		//2.用一个for循环去填值,用if去判断是否是最前边或者最后边一列,分别按照规则填值。
		for(int i = 0;i < 10;i++){
			yanghui[i] = new int[i+1]; //第0行也有1个元素,第n行有n+1个元素
			for(int j = 0;j < yanghui[i].length;j++){
				//2.1给首末元素赋值
				if(j == 0 || j == yanghui[i].length - 1){
								//每一行的第一个元素和最后一个元素都是 1
					yanghui[i][j] = 1;
				//2.2 给每行的非首末元素赋值	
				}else{
					yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
				}
		//3.输出		
				System.out.print(yanghui[i][j] + " ");
			}
							//每一行打印一个换行
			System.out.println();
		}
	}
}


Tips

1、main方法中的变量都是局部变量,储存在栈里边。

局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

2、引用类型的变量只有两种值,null 或者 地址值

3、一维数组名和二维数组名之间也不能相互赋值。二维不能赋值给一维,虽然都是地址值,但地址值前还有变量的类型。如二维地址打印出来前边还会显示"[["

数组的常用算法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-41HCiyUG-1635843764702)(Java.assets/image-20211027150618949.png)]

数组元素的赋值

1、杨辉三角(见上)
2、回形数

求数值型数组中元素的max、min、ave、sum等

1、Math.random()函数返回一个在[0.0,1)之间的double类型的值。

公式:

获取[a,b]范围内的随机数: (int)(Math.random() * (b - a + 1) + a)


package com.atguigu.java;
/*
 * 算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等
 * 
 * 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
 * 然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。	
 * 要求:所有随机数都是两位数。
 * 
 * [10,99]
 * 公式:(int)(Math.random() * (99 - 10 + 1) + 10)
 * [0,1) * 90 >> [0,90) + 10 >> [10,100) >> [10,99]
 */
public class ArrayTest1 {
	public static void main(String[] args) {
		int[] arr = new int[10];
		
		for(int i = 0;i < arr.length;i++){
			arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10);
		}
		
		//遍历
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i] + "\t");
		}
		System.out.println();
		
		//求数组元素的最大值
		int maxValue = arr[0];
		for(int i = 1;i < arr.length;i++){
			if(maxValue < arr[i]){
				maxValue = arr[i];
			}
		}
		System.out.println("最大值为:" + maxValue);
		
		//求数组元素的最小值
		int minValue = arr[0];
		for(int i = 1;i < arr.length;i++){
			if(minValue > arr[i]){
				minValue = arr[i];
			}
		}
		System.out.println("最小值为:" + minValue);
		//求数组元素的总和
		int sum = 0;
		for(int i = 0;i < arr.length;i++){
			sum += arr[i];
		}
		System.out.println("总和为:" + sum);
		//求数组元素的平均数
		int avgValue = sum / arr.length;
		System.out.println("平均数为:" + avgValue);
	}
}

//---------------------------------------------------------

pa`	ckage com.atguigu.java;

public class ArrayTest1 {
	public static void main(String[] args) {
		//初始化数组并用循环对其赋值赋值
		int[] arr = new int[10];
		int sum,min,max,ave;
		sum = ave = 0;
		min = 99;
		max = 10;
		for(int i = 0;i < arr.length;i++){
			arr[i] = (int)(Math.random()*90 + 10);
			//计算和值
			sum += arr[i];
			//找出最值
			if(max < arr[i]){
				max = arr[i];
			} 
			if(min > arr[i]){
				min = arr[i];
			} 
		}
		//平均值
		ave = sum / arr.length;
		System.out.println("最大值为:" + max);
		System.out.println("最小值为:" + min);
		System.out.println("和值为:" + sum);
		System.out.println("平均值为:" + ave);
	}
}

数组的复制、反转、查找(线性查找、二分法查找)

1、分清楚复制赋值

赋值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0zGRY1l3-1635843764703)(Java.assets/image-20211027174803482.png)]

复制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThYCdVud-1635843764704)(Java.assets/image-20211027174846515.png)]

package com.atguigu.exer;
/*
 * 使用简单数组
(1)创建一个名为ArrayExer2的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。
 * 
 * 思考:array1和array2是什么关系?array1和array2地址值相同,都指向了堆空间的唯一的一个数组实体。
 * 拓展:修改题目,实现array2对array1数组的复制
 */
public class ArrayExer2 {
	public static void main(String[] args) {  //alt + /
		int[] array1,array2;
		
		array1 = new int[]{2,3,5,7,11,13,17,19};
		
		//显示array1的内容
		for(int i = 0;i < array1.length;i++){
			System.out.print(array1[i] + "\t");
		}
		
		//赋值  array2变量等于array1
		//不能称作数组的复制。
		array2 = array1;
        
//----------------------------------------------
       //数组的复制:
		array3 = new int[array1.length];
		for(int i = 0;i < array3.length;i++){
			array3[i] = array1[i];
		}
        
//----------------------------------------------		
		//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
		for(int i = 0;i < array2.length;i++){
			if(i % 2 == 0){
				array2[i] = i;
			}
			
		}
		System.out.println();
		//打印出array1
		for(int i = 0;i < array1.length;i++){
			System.out.print(array1[i] + "\t");
		}
	}
}

2、查找

1、字符串是否相等用 dest.equals() line50

2、判断是什么条件结束的循环,用flag标记一下

3、二分法查找前提,数组有序

package com.atguigu.java;
/*
 * 算法的考查:数组的复制、反转、查找(线性查找、二分法查找)
 * 
 * 
 */
public class ArrayTest2 {
	
	public static void main(String[] args) {
		
		String[] arr = new String[]{"JJ","DD","MM","BB","GG","AA"};
		
		
		//数组的复制(区别于数组变量的赋值:arr1 = arr)
		String[] arr1 = new String[arr.length];
		for(int i = 0;i < arr1.length;i++){
			arr1[i] = arr[i];
		}
		
		//数组的反转
		//方法一:    两个元素的和是一个常数 length - 1
        
//		for(int i = 0;i < arr.length / 2;i++){
//			String temp = arr[i];
//			arr[i] = arr[arr.length - i -1];
//			arr[arr.length - i -1] = temp;
//		}
		
		//方法二:
//		for(int i = 0,j = arr.length - 1;i < j;i++,j--){
//			String temp = arr[i];
//			arr[i] = arr[j];
//			arr[j] = temp;
//		}
		
		//遍历
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i] + "\t");
		} 
		
		System.out.println();
		//查找(或搜索)
		//线性查找:
		String dest = "BB";
		dest = "CC";
		
		boolean isFlag = true;
		
		for(int i = 0;i < arr.length;i++){
			
			if(dest.equals(arr[i])){
				System.out.println("找到了指定的元素,位置为:" + i);
				isFlag = false;
				break;
			}	
		}
		if(isFlag){
			System.out.println("很遗憾,没有找到的啦!");
		}
        
		//二分法查找:(熟悉)
		//前提:所要查找的数组必须有序。
		int[] arr2 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
		
		int dest1 = -34;
		dest1 = 35;
		int head = 0;//初始的首索引
		int end = arr2.length - 1;//初始的末索引
		boolean isFlag1 = true;
		while(head <= end){
			
			int middle = (head + end)/2; //此处直接除以2即可
			
			if(dest1 == arr2[middle]){
				System.out.println("找到了指定的元素,位置为:" + middle);
				isFlag1 = false;
				break;
			}else if(arr2[middle] > dest1){
				end = middle - 1;
			}else{//arr2[middle] < dest1
				head = middle + 1;
			}
		}
	
		if(isFlag1){
			System.out.println("很遗憾,没有找到的啦!");
		}	
	}
}

数组元素的排序算法

排序算法的介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVGMsIug-1635843764705)(Java.assets/image-20211028113109507.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IC6SzWtA-1635843764706)(Java.assets/image-20211028113126918.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCDR4QCe-1635843764707)(Java.assets/image-20211028113208330.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ad0VktXy-1635843764709)(Java.assets/image-20211028113219292.png)]

1、冒泡排序(BubbleSort)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rvpo1se8-1635843764710)(Java.assets/image-20211027215821457.png)]

package com.atguigu.java;
/*
 * 数组的冒泡排序的实现
 * 
 */
public class BubbleSortTest {
	public static void main(String[] args) {
		
		int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};
		
		//冒泡排序
        //外层循环决定冒泡的次数,n个元素执行n-1次
		for(int i = 0;i < arr.length - 1;i++){
            //内层循环一次表示一个数冒泡到最后或者最前,这个数之后不参与排序
			for(int j = 0;j < arr.length - 1 - i;j++){	
				if(arr[j] > arr[j + 1]){
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}		
			}	
		}
		//输出
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i] + "\t");
		}
	}
}
2、快速排序(QuickSort)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oap8K0Gz-1635843764711)(Java.assets/image-20211027215941253.png)]


package com.atguigu.java;

/**
 * 快速排序
 * 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
 * 则分别对这两部分继续进行排序,直到整个序列有序。
 * @author shkstart
 * 2018-12-17
 */
public class QuickSort {
	private static void swap(int[] data, int i, int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

	private static void subSort(int[] data, int start, int end) {
		if (start < end) { //递归出口
			
//----------------------------------------------------------------
			int base = data[start];
			int low = start;
			int high = end + 1; //后边--high,是先-1再读值
			while (true) {
				//此处不能改成 low < high,此种写法需要出循环时 high == low -1,此时再把high位置填上枢轴值
				while (low < end && data[++low] - base <= 0)
					;
				while (high > start && data[--high] - base >= 0)
					;
				if (low < high) {
					swap(data, low, high);
				} else {
					//此时high == low -1
					break;
				}
			}
			swap(data, start, high);
			
			subSort(data, start, high - 1);//递归调用
			subSort(data, high + 1, end);
//------------------------------------------------------------------
/* my
 * 这种写法不用swap函数。  最后把base填入low或者high即可。因为出循环时low == high
 			
 			int base = data[start];
			int low  = start;
			int high = end;
			
			while(low < high){
				
				while(low < high && data[high] >= base){
					--high;
				}
					data[low] = data[high];
				while(low < high && data[low] <= base){
					++low;
				}
					data[high] = data[low];
			}
			
			//出循环时候 low == high
			data[low] = base;
			//递归调用
			subSort(data,start,low - 1);
			subSort(data,low + 1,end);
	
 */
			
		}
	}
	
	public static void quickSort(int[] data){
		subSort(data,0,data.length-1);
	}
	//主函数
	public static void main(String[] args) {
		int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
		System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
		quickSort(data);
		System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
	}
}

老师写法过程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kSZXhxnU-1635843764711)(Java.assets/image-20211028105328336.png)]

若内层wihle循环条件改成 low < high,将导致排序失败。此种写法需要出循环时 high == low -1,此时再把high位置填上枢轴值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Le57FNK9-1635843764712)(Java.assets/image-20211028110310281.png)]

my:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YBZgVy35-1635843764713)(Java.assets/image-20211028105404082.png)]

Arrays工具类的使用

可以直接到API文档里边搜索Arrays

常用的几种工具类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKZcvkrZ-1635843764714)(Java.assets/image-20211028112921238.png)]

package com.atguigu.java;

import java.util.Arrays;

/*
 * java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
 * 
 * 
 */
public class ArraysTest {
	public static void main(String[] args) {
		
		//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
		int[] arr1 = new int[]{1,2,3,4};
		int[] arr2 = new int[]{1,3,2,4};
		boolean isEquals = Arrays.equals(arr1, arr2);
		System.out.println(isEquals);
		
		//2.String toString(int[] a):输出数组信息。
		System.out.println(Arrays.toString(arr1));
		
			
		//3.void fill(int[] a,int val):将指定值填充到数组之中。
		Arrays.fill(arr1,10);
		System.out.println(Arrays.toString(arr1));
		

		//4.void sort(int[] a):对数组进行排序。
		Arrays.sort(arr2);
		System.out.println(Arrays.toString(arr2));
		
		//5.int binarySearch(int[] a,int key)
		int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
		int index = Arrays.binarySearch(arr3, 210);
		if(index >= 0){
			System.out.println(index);
		}else{
			System.out.println("未找到");
		}	
	}
}

数组使用中的常见异常

1、数组脚标越界异常(ArrayIndexOutOfBoundsException)

2、 空指针异常:NullPointerException

3、一旦程序出现异常,未处理,程序终止执行。

package com.atguigu.java;
/*
 * 数组中的常见异常:
 * 1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
 * 
 * 2. 空指针异常:NullPointerException
 * 
 */
public class ArrayExceptionTest {
	public static void main(String[] args) {
		
		//1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
		int[] arr = new int[]{1,2,3,4,5};
		
//		for(int i = 0;i <= arr.length;i++){
//			System.out.println(arr[i]);
//		}
		
//		System.out.println(arr[-2]);
		
//		System.out.println("hello");
		
		//2.2. 空指针异常:NullPointerException
		//情况一:
//		int[] arr1 = new int[]{1,2,3};
//		arr1 = null;
//		System.out.println(arr1[0]);
		
		//情况二:
//		int[][] arr2 = new int[4][];
//		System.out.println(arr2[0][0]);
		
		//情况三:
		String[] arr3 = new String[]{"AA","BB","CC"};
		arr3[0] = null;
		System.out.println(arr3[0].toString());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值