本篇 Java 的学习路线是参考韩顺平老师的教程
教程:零基础 30 天学会 Java
https://www.bilibili.com/video/BV1fh411y7R8

之前学习编程的时候并没有一个良好的记录习惯,这些技能平时工作上又用不上,导致时间长了基本都忘完了,不得已只好从头再学一遍


# Java 语言的特点

  1. Java 语言是面向对象的(oop)

  2. Java 语言是强类型语言,Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序强壮性的重要保证

  3. Java 是跨平台性的

通过 javac 编译源程序.java (源文件),生成源程序.class (字节码文件), 这个源程序.class 字节码文件可以通过 JVM 实现在不同的操作系统平台运行

upload successful

  1. Java 是解释型语言

解释型语言和编译型语言的区别:解释型语言不能直接被机器执行,需要由解释器执行,编译型语言通过编译后的代码可以直接被机器执行


# Java API

API (Application Programming Interface) 是 JAVA 提供的基本编程接口,这些接口是 JAVA 自身提供的类和方法,可以直接调用,极大程度上减轻了开发者的工作量

中文在线文档 https://www.matools.com

  • How to use ?

  • Package --> Class --> Mathod

upload successful


# 基础语法

和以往学过的任何编程语言一样,开头还是熟悉的 hello world ,语法结构大同小异,看不懂也没关系,前期靠的是多敲代码,熟悉基本的原理和基本的语法,程序能正常跑起来就行了,随着学习的深入,自然会了解每一行的代码的意思

hello

这里有一件比较有意思的事,就是通过 javac源程序.java 编译成源程序.class, 使用 java 运行源程序.class 时不需要加上后缀,如果加上后缀的话程序会报错,提示找不到或无法加载主类源程序.class, 这是因为类并不总是从 .class 文件加载,有时它们来自 JAR 包,有时它们来自互联网,有时它们是由程序动态构建的等等,所以我们运行的时候,只需要执行类名即可

a
//public class Hello 表示 Hello 是一个属于 public 的类
public class Hello{
	//public static void main (String [] args) 是程序的入口
	pubilc statis void main(String[] args){
    
    // System.out.println 表示把括号内的内容输出到屏幕并换行
    System.out.println("hello world");
   }
}

# Java 开发规范

  1. Java 源文件以.java 为扩展名,源文件的基本组成部分是类 (class)

  2. Java 应用程序的执行入口是 main () 方法

  3. Java 语言严格区分大小写

  4. Java 方法由一条条语句构成,每个语句以 ";" 结束

  5. 大括号是成对出现的,缺一不可,需要养成先写 {} 再写代码的习惯

  6. 一个源文件中最多只能有一个 public 类,其它类的个数不限

  7. 如果源文件包含一个 public 类,则文件名必须按照该类名命名

  8. 一个源文件中最多只能有一个 public 类,其它类的个数不限,也可以将 main 方法写在非 public 类中,然后指定运行非 public 类,这样入口方法就是非 public 的 main 方法


# 文档注释

注释内容可以被 JDK 提供的工具 javadoc 解析,生成一套以网页文件形式体现的该程序说明文档

  • example
a
/**
 * @author      Bob
 * @version     1.0.0
 */
public class Comment{
        public static void main(String[] args){
                System.out.println("Comment example!");
        }
}
a
// 使用 javadoc 生成说明文档
javadoc -d /tmp/ -author -version Comment.java
  • 运行结果

upload successful

这里有个警告,好像是说 main 方法没有注释,无需理会,打开生成的 index.html,可以看到 author 和 version 的信息已经出现在文档里面了

  • index.html

upload successful


# 转义字符

和其它语言一样,如果希望程序输出一些特殊的符号,需要使用转义字符将其输出,这里只挑几个常用的转义字符进行说明

转义字符 意义
\t 水平制表 (Tab 键)
\n 换行符
\ \ 反斜线字符 "\"
\' 单引号 ' 字符
\" 双引号 " 字符
\r 回车
  • example
a
public class Escape{
	public static void main(String[] args){
		
		System.out.println("China\tGuangDong\tGuangZhou");
		System.out.println("c:\\windows\\system32\\drivers");
		System.out.println("\"Lift is \'short\',your need keep \'learning\'\"");
		System.out.println("89345\r12");
	}
  • 输出结果
a
水平制表符
China	GuangDong	GuangZhou
反斜杠
c:\windows\system32\drivers
单引号和双引号
"Lift is 'short',your need keep 'learning'"
回车
12345
  • 运行结果

upload successful

其它转义字符还是比较容易理解的,这个只讲解一下换行符和回车的区别,换行符相信大家都知道是光标移动到下一行字符的起始位置,而回车则是光标移动到当行的字符起始位置,所以代码中的 98345\r12 执行结果为 12345


# 变量

变量是程序的基本组成单位,变量由类型+名称+值组成,先申明变量类型,然后给变量赋值,也可以在申明变量类型的时候直接给变量赋值

a
public class Variables{
	public static void main(String[] args){
 
 		int a;	// 定义一个变量,数据类型为 int 整型,变量名称为 a
        
        a = 5;	// 把整数 5 赋值给变量 a
        
    	int b = 10;	// 定义一个变量,数据类型为 int 整型,变量名称为 b,值为 10
        
        System.out.printlp(a + "\n" + b); // 输出变量 a 和 b 到屏幕
    }    
}
  • 运行结果

upload successful

+ 是连接符号,和 pythpon 一样,可以将不同的数据类型连接起来,相同数据类型结果相加,不同数据类型起到拼接作用,下面通过代码了解它的作用

a
public class Plus{
        public static void main(String[] args){
				
                // 两个整型为结果相加
                System.out.println(100 + 20);
				
                // 整型和字符串为拼接作用,拼接后为字符串类型
                System.out.println(100 + "20");
				
                // 这里先计算整型结果,然后再和字符串拼接
                System.out.println(100 + 20 + "hello");
                
				// 这里先把 hello 和 100 拼接,拼接后结果依然是字符串,然后再和 20 拼接
                System.out.println("heloo" + 100 + 20);
        }
}
  • 运行结果

upload successful

不管是什么数据类型,只要和字符串类型拼接后,就会变成字符串类型


# 数据类型

不同的数据类型在内存中开启不同的空间大小 (字节),前面使用的 int 整型长度为 4 个字节,1 个字节由 8 位二进制组成,也就是说 int 有效值范围是 2^32,转换成有符号十进制数取值范围是 -2147483648 ~ 2147483647 , 日常计数一般是够用的了

  • Java 数据类型

upload successful

String 不是数据类型,String 是一个类,boolean 只能用 true 和 false 表示,不能用非 0 和 0 表示

  • example
a
public class DataType{
        public static void main(String[] args){
                byte a = 1;
                boolean b = true;
                char c = 'c'; //char 本质上是整数,可以进行运算
                short d = 12345;
                float e = 0.1234567890123f;
                int f = 1234567890;
                long g = 1234567890123456789L;
                double h = 1.12345678901234567890;
                System.out.println(a);
                System.out.println(b);
                System.out.println(c);
                System.out.println(d);
                System.out.println(e);
                System.out.println(f);
                System.out.println(g);
                System.out.println(h);
        }
}
  • 运行结果

upload successful

整型赋值超出取值范围时,编译时报错,浮点型赋值超出取值范围时,编译通过,但尾数超出范围部分会丢失


# 浮点数陷阱

要避免使用浮点数进行运算比较,因为小数是一个近似值,并不是一个精准的数字,在计算中会丢失精度

  • example
a
public class FloatDetail{
        public static void main(String[] args){
        
                double num1 = 2.7;
                double num2 = 8.1 / 3; // 计算结果为一个无限接近 2.7 的小数
                if (num1 == num2){
                        System.out.println("True!");
                }else{
                        System.out.println("False!");
                }
       }
}
  • 运行结果

upload successful

如果一定要用浮点数的运算结果进行比较,正确的方法是使用 Math.abs () 函数返回 num1 减去 num2 差的绝对值进行判断,如果该返回值小于自定义的一个精度,那么我们可以认为这两个数是相等的

  • example
a
public class FloatDetail{
        public static void main(String[] args){
                double num1 = 2.7;
                double num2 = 8.1 / 3; // 计算结果为一个无限接近 2.7 的小数
                if (Math.abs(num1 - num2) < 0.00000001){
                        System.out.println("True!");
                }else{
                        System.out.println("False!");
                }
        }
}
  • 运行结果

upload successful


# 数据类型转换

当 Java 程序在进行赋值或者运算时,精度小的类型自动转换成精度大的数据类型

  1. char --> int --> long --> float --> double

  2. byte --> short --> int --> long --> float --> double

  • example
a
// 程序先判断 'c' 为 char [1] 类型,a 为 int [4] 类型,由于 char [1] < int [4], 根据自动转换规则,char 会自动转换成 int 类型
int a = 'c';
double d = 80; // 同上
// 这里编译出错,程序先判断 1.1 为 double [8] 类型,c 为 float [4] 类型,容量较大的 double 无法存放在容量较小的 float 内存中,程序报错
float c = a + 1.1; 
byte a1 = 10; //byte 取值范围在 -128 ~ 127,编译通过
int a2 = 10;
byte a3 = a2; // 编译报错,a2 为 int [4] 类型
short a4 = a1; // 编译报错,a1 为 byte [1] 类型,byte [1] 不能和 short [3] 实现转换

byte、short、char 三者可以进行计算,但是计算时首先转换成 int 类型

有多种类型的数据混合计算时,系统会自动将所有的书记转换成容量最大的数据类型,然后再进行计算

  • example
a
public class AutoConvert{
        public static void main(String[] args){
                char a = 'a';
                short b = 80;
                int c = 100;
                double d =1.1;
                System.out.println(a+b+c+d);
        }
}
  • 运行结果

upload successful


# 基本数据类型与字符串类型互转
  1. 基本类型转换字符串类型
  • example
a
public class BasicToStr{
        public static void main(String[] args){
                int a = 10;
                float b = 3.14f;
                char c = 'a';
                String a1 = a + "";
                String b1 = b + "";
                String c1 = c + "";
                System.out.println(a1 + "\t" + b1 + "\t" + c1);
        }
}
  • 运行结果

upload successful

  1. String 类型转基本类型

String 类型转换基本类型通过调用包装类 parseXX 方法

  • example
a
public class StrToBasic{
        public static void main(String[] args){
                String a = "100";
                int a1 = Integer.parseInt(a);
                double a2 = Double.parseDouble(a);
                float a3 = Float.parseFloat(a);
                byte a4 = Byte.parseByte(a);
                boolean a5 = Boolean.parseBoolean("true");
                System.out.println(a1);
                System.out.println(a2);
                System.out.println(a3);
                System.out.println(a4);
                System.out.println(a5);
                
                // 字符串转字符通过 charAt () 函数取字符串中任意字符
                System.out.println(a.charAt(0));
        }
}
  • 运行结果

upload successful


# 运算符

运算符这个没什么好说的,跟任何一门语言一样,都是算术运算符、逻辑运算符、关系运算符、赋值运算符和位运算符等,用法和优先级基本一样


# 算术运算符

算术运算符 描述
+ 加号、正号、连接符
- 减号和负号
* 乘号
/ 除号
% 取余
++ 自增
-- 自减
  • Exercise 1

    程序输出假如还有 59 天放假,合计 XX 个星期零 XX 天

a
public class ArithmeticOperator{
        public static void main(String[] args){
			
                // 定义总天数、星期、天三个变量
                int days = 59;
                int week = days / 7;
                int day = days % 7;
                System.out.println("还有" + days + "天放假,合计" + week + "个星期零" + day + "天");
        }
}
  • 运算结果

upload successful

  • Exercise 2

    定义一个变量保存华氏温度,华氏温度转摄氏度的公式为:5 / 9 * (华氏温度 - 100), 求华氏温度 234.5 对应的摄氏度

a
public class Fahrenheit{
       public static void main(String[] args){
   			// 定义华氏度
               double f = 234.5;
               
               
// 定义华氏度转换摄氏度公式,需要注意不能直接把公式搬过来,因为如果是 int 类型的 5 / 9 结果等于 0 ,那么这个公式计算出来的结果就是 0,这里需要把 5 / 9 的结果转换成 double 类型,根据自动转换类型规则,只要其中一个数为 double 类型,其结果就是 double 类型
               double s = 5 / 9.0 * (f - 100);
               System.out.println("华氏度 " + f + " 转换成摄氏度后为: " + s);
       }
}
  • 运行结果

upload successful

a % b 当 a 为小数时,公式为 a - (int) a /b * b


# 关系运算符

关系运算符 描述
== 相等于
!= 不等于
< 小于
> 大于
<= 小于等于
>= 大于等于
instanceof 检查是否是类的对象

该关系运算符过于简单,懒得敲代码


# 逻辑运算符

逻辑运算符 描述
&& 逻辑与,两个操作数都为真,结果为 true
|| 逻辑或,两个操作数其中一个为真,结果为真
逻辑非,结果取反,true 为 false,false 为 true
  • && 例子
  1. true && true == true
  2. true && false == false
  3. flase && true == false
  4. flase && flase == false
  • || 例子
  1. true || true == true
  2. true || flase == true
  3. flase || true == true
  4. flase || flase == flase
  • ! 例子
  1. !true == false
  2. !false == true
  • example
public class LogicOperator{
        public static void main(String[] args){
                int a = 10;
                if ( a++ == 11 && a > 10 ){
                        System.out.println("true");
                        a = 100;
                }
                System.out.println("a = " + a);
        }
}
  • 运行结果

upload successful

逻辑运算符只有一个注意要点,就是短路问题,当第一个条件满足时,后面的条件不作执行


# 赋值运算符

赋值运算符 描述
= 给变量赋值
+= 先加再赋值
-+ 先减再赋值
*= 先乘再赋值
/= 先除再赋值
%= 先取余再赋值

a += 10 == a = a + 10 // 其它类推

这里只需要注意一个点,就是类型转换的问题,复合赋值运算符会进行数据类型的强制转换转换

  • example
a
public class GetType{
        public static void main(String[] args){
                byte a = 127;
                byte b = 3;
                System.out.println("a = " + a + " ,datatype is " + getType(a));
                System.out.println("b = " + b + " ,datatype is " + getType(b));
                a += 1;
                b = b + 2;
                System.out.println("a = " + a + " ,datatype is " + getType(a));
                System.out.println("b = " + b + " ,datatype is " + getType(b));
                a++;
                b = b + 1;
                System.out.println("a = " + a + " ,datatype is " + getType(a));
                System.out.println("b = " + b + " ,datatype is " + getType(b));
        }
        public static String getType(Object a){
                return a.getClass().toString();
        }
}
  • 编译结果

upload successful

从编译中可以发现 += 和 ++ 中结果会自动转换成 byte 类型,等价于 a = (byte)(a + 1), 如果拆分开来,数字将自动转换成 int 类型


# 三元运算符

表达式?表达式 1: 表达式 2;

  • example
a
int a = 10;
int b =20;
int result = a > b ? a++: b--;

# 位运算符

位运算符 描述
>> 算术右移,低位溢出,符号位不变,右移 1 位等于除于 2
<< 算术左移,符号位不变,低位补 0,左移 1 位等于乘于 2
>>> 无符号右移,低位溢出,高位补 0
~ 按位取反,1 为 0,0 为 1
& 按位与,两边都是 1,结果为 1,否则为 0
| 按位或,两边只要有 1. 结果为 1,否则为 0
^ 按位异或,两边不一样,结果为 1,否则为 0

位运算先求数的补码,将补码进行位运算,然后结果以原码返回

  • Exercise

14 & (-8) = ?

  1. 14 的补码为 00000000 00000000 00000000 00001110

  2. -8 的原码为 10000000 00000000 00000000 00001000

    -8 的反码为 11111111 11111111 11111111 11110111

    -8 的补码为 11111111 11111111 11111111 11111000

  3. 进行与运算

    | 十进制 | 二进制 (补码)|
    |:-😐:-😐
    |14|00000000 00000000 00000000 00001110|
    |-8|11111111 11111111 11111111 11111000|
    | 与运算结果 | 00000000 00000000 00000000 00001000|

    由于结果最高位为 0,表示这个数是个正数,正数的补码原码一样,所以 14 & (-8) = 8


~-11 = ?

  1. -11 的原码为 10000000 00000000 00000000 00001011

  2. -11 的反码为 11111111 11111111 11111111 11110100

  3. -11 的补码为 11111111 11111111 11111111 11110101

    | 十进制 | 二进制 (补码)|
    |:-😐:-😐
    |-11|11111111 11111111 11111111 11110101|
    | 取反结果 | 00000000 00000000 00000000 00001010|

    由于结果最高位为 0,表示这个数是个正数,正数的补码原码一样,所以 ~-11 = 10


~21 = ?

  1. 21 的补码为 00000000 00000000 00000000 00010101

    | 十进制 | 二进制 (补码)|
    |:-😐:-😐
    |21|00000000 00000000 00000000 00010101|
    | 取反结果 | 11111111 11111111 11111111 11101010|

    | 由于结果最高有效位为 1,表示这个数为负数,需要将补码转换成原码 ||

    | 补码 | 11111111 11111111 11111111 11101010|
    | 反码 | 11111111 11111111 11111111 11101001|
    | 原码 | 10000000 00000000 00000000 00010110|

    所以 ~21 = -22


7 | 9 = ?

  1. 7 的补码为 00000000 00000000 00000000 00000111

  2. 9 的补码为 00000000 00000000 00000000 00001001

    十进制 二进制 (补码)
    7 00000000 00000000 00000000 00000111
    9 00000000 00000000 00000000 00001001
    或运算结果 00000000 00000000 00000000 00001111
    由于结果最高位为 0,表示这个数是个正数,正数的补码原码一样,所以 7 9 = 15

4 ^ 3 = ?

  1. 4 的补码为 00000000 00000000 00000000 00000100

  2. 3 的补码为 00000000 00000000 00000000 00000011

    十进制 二进制 (补码)
    4 00000000 00000000 00000000 00000100
    3 00000000 00000000 00000000 00000011
    异或运算结果 00000000 00000000 00000000 0000111

    由于结果最高位为 0,表示这个数是个正数,正数的补码原码一样,所以 4 ^ 3 = 7

  • Code
a
public class BitOperator{
        public static void main(String[] args){
                System.out.print("14 & (-8) = ");
                System.out.println( 14&-8 );
                System.out.print("~-11 = ");
                System.out.println( ~-11 );
                System.out.print("~21 = ");
                System.out.println(~21);
                System.out.print("7 | 9 = ");
                System.out.println( 7 | 9 );
                System.out.print("4 ^ 3 = ");
                System.out.println( 4 ^ 3);
        }
}
  • 运行结果

upload successful

Java 中的数都是有符号数,Java 没有无符号数

# 控制结构

控制结构一般分为顺序控制、分支控制和循环控制三种

# 顺序控制

程序从上到下逐行执行,中间没有任何判断和跳转

  • Code
a
int num1 = 100;
    int num2 = num1++;

# 分支控制

让程序有选择的执行

  1. 单分支
  • 基本语法:

if (表达式){

执行代码语句;(可以多条语句)
}

当条件表达式为 true 时,执行 {} 的语句,当条件表达式为 false 的时候,语句不执行

  • Code
a
import java.util.Scanner;
public class IfExercise{
        public static void main(String[] args){
                Scanner scanner = new Scanner(System.in);
                System.out.print("请输入你的年龄:");
                int age = scanner.nextInt();
                if (age >= 18 && age < 30){
                        System.out.println("恭喜你,你现在还是小鲜肉的年龄!");
                }
                System.out.println("拜拜了您");
        }
}
  • 运行结果

upload successful

  1. 双分支
  • 基本语法:

if (表达式){

执行代码语句 1;
}else{
执行代码语句 2;
}

当条件表达式结果为 true 时,执行代码语句 1,当条件表达式为 false 的时候,执行代码语句 2

  • Code
a
import java.util.Scanner;
public class IfElseExercise{
        public static void main(String[] args) throws InterruptedException{
                String s = "杰哥:“你看这个彬彬,才喝了几罐,就醉了,真是太逊了。”\n阿伟:“这个彬彬就是逊啦!”\n杰哥:“哦?这么说,你很勇哦?”\n阿伟:“开玩笑,我超勇的!超会喝的啦!”\n杰哥:“超会喝,很勇嘛,身材不错,蛮结实的嘛。”\n阿伟:“杰,杰哥,你干嘛?!”\n杰哥:“哎呦,都多大了,还害羞?我看你是完全不懂哦?”\n阿伟:“懂。。?懂什么啊?”\n杰哥:“你想懂?我房>里有些好康的。”\n阿伟:“好康?是新游戏哦?”\n杰哥:“哎呀什么游戏,比游戏还刺激,还能教你登duang郎哦?”\n\n";
        for (int i = 0; i < s.length();i++){
                System.out.print(s.charAt(i));
                Thread.sleep(100);
                }
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入数字 \"1\" 进入房间:");
        int answer = sc.nextInt();
        if( answer == 1 ){
                System.out.println("\n阿伟:“杰,杰哥,你干嘛啦? 不要啊!!!”");
                System.out.println("杰哥一拳过去:“听话!”");
                System.out.println("阿伟随即晕了过去,醒来后发现自己已经不干净了,此时阿伟才明白杰哥口中的duang郎真正的含义");
                System.out.println("\n通过这个故事,希望你要明白男孩子在外也一定要保护好自己哦");
        }else{
                System.out.println("\n恭喜你逃过一杰 ^_^");
                System.out.println("虽然你逃过了一杰,但是同时你也失去了duang郎的机会!");
                System.out.println("你个小屁孩,希望你下次可要考虑清楚了哦!!!");
        }
    }
}
  • 运行结果

upload successful

  • 判断一个年份是否是闰年

判断闰年的条件为下面两条之中任意一条即可:
1. 年份能被 4 整除,但是不能被 100 整除
2. 能被 400 整除

a
import java.util.Scanner;
public class Leapyear{
        public static void main(String[] args){
                System.out.println("This a test leapyear little program...");
                Scanner sc = new Scanner(System.in);
                System.out.print("请输入一个年份:");
                int year = sc.nextInt();
                if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
                        System.out.println(year + "是闰年");
                }else{
                        System.out.println(year + "不是闰年");
                }
        }
}
  • 运行结果

upload successful

  1. 多分支
  • 基本语法:

if (表达式 1){

执行代码语句 1;
} else if (表达式 2){
执行代码语句 2;
}...{
}else{
执行代码语句 n;}

当条件表达式结果为 true 时,执行代码语句 1,当条件表达式为 false 的时候,判断 else if 表达式是否为 true,true 执行里面的语句,判断到最后为 false 执行 else 语句

  • Code
a
public class RandomEat{
        public static void main(String[] args){
                System.out.println("这是一个吃饭选择困难症患者和胖子减肥的福利小程序,希望你能坚持下去...");
                double random = Math.random() * 1000;
                if ((int)random % 9 == 1){
                        System.out.println("今天吃可乐泡饭");
                }else if((int)random % 9 == 2){
                        System.out.println("今天喝豆汁伴咖啡");
                }else if((int)random % 9 == 3){
                        System.out.println("今天吃臭豆腐炒鸭蛋");
                }else if((int)random % 9 == 4){
                        System.out.println("今天吃烤榴莲");
                }else if((int)random % 9 == 5){
                        System.out.println("今天吃鲱鱼罐头");
                }else if((int)random % 9 == 6){
                        System.out.println("今天请全村人吃席");
                }else if((int)random % 9 == 7){
                        System.out.println("今天吃纳豆炒皮蛋");
                }else{
                        System.out.println("今天不吃减肥");
                }
        }
}
  • 运行结果

upload successful

# 循环控制

  • 基本语法:
    for (初始化表达式;条件表达式;尾部循环体){
    执行语句块...;
    }

  • Exercise

打印棱形图案

a
public class ForExercise{
	public static void main(String[] args){
		/**                      *				*
		 * 	        	* *			       ***
		 * 		       *   *			      *****
		 *		      *     *			     *******
		 *                   *       *					
		 * 		      *     *		*******			
		 * 	               *   * 		 *****			 
		 * 			* *               ***                   
		 * 			 *         	   *
		 */
		
		// 将棱形分成上下两部分
		// 上面为正三角,下面为倒三角
		// 定义上层和底层变量
		int upperlayer = 10, lowerlayer = upperlayer * 2 - 3;
			
		
		for(int i = 1; i <= upperlayer; i++){			// 定义上层层数
			for(int k = 1; k <= upperlayer - i; k++){	// 控制每层第一个 * 前面的空格
				System.out.print(" ");
			}
			for(int j = 1; j <= i * 2 - 1; j++){		// 控制每层输出 * 的个数
				if(j == 1 || j == i * 2 - 1){		// 只打印本层第一个 * 和最后一个 *,中间用空格代替
		
					System.out.print("*");
				
				}else{
					System.out.print(" ");		
				}
			}
			System.out.println();
		}
		for(int i1 = 1; i1 <= upperlayer; i1++){		// 定义下层层数
			for(int k1 = 1; k1 <= i1; k1++){		// 控制每层第一个 * 前面的空格
				
				System.out.print(" ");
			}
			for(int j1 = lowerlayer; j1 >= i1 * 2 -1 ; j1--){	// 控制每层输出 * 的个数
				
				if(j1 == i1 * 2 -1 || j1 == lowerlayer){	// 只打印本层第一个 * 和最后一个 *,中间用空格代替
				
					System.out.print("*");					
				
				}else{
					
					System.out.print(" ");	
				}
				
			}
			System.out.println();
		}
		
	}
}
  • 运行结果

upload successful

# 数组

# 一维数组

数组可以存放多个同一类型数据,数组也是一种数据类型,是应用类型。
即数组就是一组数据

  • 动态初始化
    语法: 数据类型 数据名 [] = new 数据类型 [元素个数];
  1. double a[] = new double[5];
    申明变量和分配内存空间同时进行

  2. double a []; // 申明变量
    a = new double [5]; // 用 new 分配内存空间

  • Exercise

统计一个班级 5 个学生的成绩,输出成绩总和,并输出最高分和最低分的成绩

a
import java.util.Scanner;
public class Array02{
	public static void main(String[] args){
	
		// 定义一个数组名为 scores,数据类型为 double,元素数量为 5 的数组
		double scores[] = new double[5];
		
		// 获取数组元素个数
		int length = scores.length;
		// 定义一个变量统计成绩总和
		double sum = 0;
		
		// 定义一个临时变量用于交换数组元素位置
		double temp = 0;
		// 定义一个 Scanner 对象用于接收用户输入
		Scanner sc = new Scanner(System.in);
		// 用 for 循环提示用户输入学生成绩
		for (int i = 0; i < scores.length; i++){
		
			System.out.print("请输入第" + (i+1) + "个学生成绩: ");
			scores[i] = sc.nextDouble();
		}
		// 统计成绩总数
		for (int i = 0; i < length; i++){
		
			sum += scores[i];
		}
		System.out.println("学生总成绩分数为: " + sum);
		// 用二层 for 循环判断成绩大小
		for (int i = 0; i < (length - 1); i++){
		
			for (int j = i+1; j < length; j++ ){
				// 将成绩分数从低到高从新排列
				if (scores[i] >= scores[j]){
				
					temp = scores[j];
					scores[j] = scores[i];
				       scores[i] = temp;	
				}
			}
		}
		System.out.println("学生成绩最高分数为: " + scores[length - 1]);
		System.out.println("学生成绩最低分数为: " + scores[0]);
	}
}
  • 运行结果

upload successful

  • 静态初始化

语法: 数据类型 数据名 [] = {元素值,元素值...};

int a[] = {1, 2, 3, 4, 5};

根据 {} 中的元素划分内存空间

等价于 int a [] = new int [5]; // 先申明数组和初始化内存空间

// 为每个元素赋值
a [0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
a[4] = 5;

  • 注意事项和细节
  1. 数组是多个相同类型数据的组合,实现对这些数据的统一管理

  2. 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用

  3. 数组创建后,如果没有赋值,有默认值
    int 0, short 0, byte 0, long 0, float 0.0 double 0.0, char \u0000, blooean false, String null

  4. 使用数组步骤:
    1. 声明数组并开辟内存空间
    2. 给数组各个元素赋值
    3. 使用数组

  5. 数组下标必须在制定范围内使用,否则报下标越界异常

  6. 数组属引用类型,数组型数据是对象 (object)

  • 数组赋值机制
  1. 值传递:基本数据类型赋值,这个值就是具体的数据,而且互相不影响

int n1 = 10; int n2 = n1;

n2 = 80; // 此时 n2 的变化不会影响到 n1 的值

  1. 引用传递:数组在默认情况下是引用传递,赋的值是地址
    int [] arr1 = {1, 2, 3};
    int[] arr2 = arr1;
    arr2 [0] = 10; // 此时 arr2 的变化 arr1 也随着变化

# 二维数组

  • 静态初始化

数据类型 [][] 数组名 = { {元素...},{元素...},{元素...} };

int[][] arr = { {1,2,3},{10,20},{100} };

int arr[][] = { {1,2,3},{10,20},{100} };

int[] arr[] = { {1,2,3},{10,20},{100} };

  • 动态初始化

数据类型 [][] 数组名 = new int [][];

int[][] arr = new int[][];

a
public class TwoDimensionalArray01{
        public static void main(String[] args){
                /** 题目:动态创建下面二维数组,并输出
                 * 1
                 * 1 2
                 * 1 2 3
                 * . . . . 
                 */
                int[][] arr = new int[10][];
                for (int i = 0; i < arr.length; i++){
                        arr[i] = new int[i + 1];
                        for (int j = 0; j < arr[i].length; j++){
                                arr[i][j] = j + 1;
                        }
                }
                for (int i = 0; i < arr.length; i++){
                        for (int j = 0; j < arr[i].length; j++){
                                System.out.print(arr[i][j] + " ");
                        }
                        System.out.println();
                }
        }
}
  • 运行结果

upload successful

此文章已被阅读次数:正在加载...Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Bob WeChat Pay

WeChat Pay

Bob PayPal

PayPal

Bob Alipay

Alipay