本文是参考廖雪峰的官方文档以及黑马57期的视频,记录一些Java快速入门的知识,方便以后复习。
(未完待续)
目录
第一章 开发前言
计算机存储单元
位(bit):一个数字0或者一个数字1,代表一位。
字节(Byte):每逢8位是一个字节,这是数据存储的最小单位。
1Byte=8bit
2KB=1024Byte
1MB=1024KB
1GB=1024MB
1TB=1024GB
1PB=1024TB
1EB=1024PB
1ZB=1024EB
命令提示符
windows:cmd
第二章 Java语言开发环境搭建
JDK:Java Development Kit
JRE:Java Runtime Environment
简单地说,JRE就是运行Java字节码的虚拟机。但是,如果只有Java源码,要编译成Java字节码,就需要JDK,因为JDK除了包含JRE,还提供了编译器、调试器等开发工具。
简单的说:
运行:JRE
开发:JDK
核心:JVM
记事本打开的两种方法:
第三章 HelloWorld入门程序
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello,World! ");
}
}
一般来说:
第一行:这个定义被称为class(类),类名是Hello
,大小写敏感,class
用来定义一个类,public
表示这个类是公开的,public
、class
都是Java
的关键字,必须小写,Hello
是类的名字,按照习惯,首字母H
要大写。而花括号{}
中间则是类的定义。
第二行:所有程序执行的起点。 方法是可执行的代码块,一个方法除了方法名main
,还有用()
括起来的方法参数,这里的main
方法有一个参数,参数类型是String[]
,参数名是args
,public
、static
用来修饰方法,这里表示它是一个公开的静态方法,void
是方法的返回类型,而花括号{}
中间的就是方法的代码。
第三行:方法的代码每一行用;
结束,它用来打印一个字符串到屏幕上。
执行:
在执行的时候,这两种写法都可,一般第二种。
注意,若是代码改写为:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello,World!!! ");
}
}
执行:
为什么不是
Hello,World!!!
,原因:
java
执行的是编译好的class
文件,改代码之后需要重新编译
不用手动删除原来的class
文件,新文件会代替旧文件。
第四章 Java程序基础
Java程序基本结构
类名要求:
类名必须以英文字母开头,后接字母,数字和下划线的组合
习惯以大写字母开头
注意:
public
是访问修饰符,表示该class是公开的。不写public
也能正确编译,但是这个类将无法从命令行执行。
注释:
单行注释://
多行注释:/* */
特殊的多行注释:/** */
可以用来自动创建文档
变量和数据类型
变量分为两种:基本类型的变量和引用类型的变量。
基本类型的变量
int x = 1;
若不写初始值,则默认值是0
。
第一次定义变量x
的时候,需要指定变量类型int
,第二次重新赋值的时候,变量x
已经存在了,不能再重复定义,因此不能指定变量类型int
。
基本数据类型:
基本数据类型是CPU可以直接进行运算的类型。Java定义了以下几种基本数据类型:
整数类型:byte,short,int,long
浮点数类型:float,double
字符类型:char
布尔类型:boolean
注意:char类型使用单引号'
,且仅有一个字符,要和双引号"
的字符串类型区分开。
引用类型
除了上述基本类型的变量,剩下的都是引用类型。例如,引用类型最常用的就是String
字符串:
String s = "hello";
引用类型的变量类似于C语言的指针,它内部存储一个“地址”,指向某个对象在内存的位置。
常量:
定义变量的时候,如果加上final
修饰符,这个变量就变成了常量:
final double PI = 3.14; // PI是一个常量
根据习惯,常量名通常全部大写。
var关键字
有些时候,类型的名字太长,写起来比较麻烦。例如:
StringBuilder sb = new StringBuilder();
等同于:
var sb = new StringBuilder();
编译器会根据赋值语句自动推断出变量sb
的类型是StringBuilder
。
变量的作用范围
{
...
int i = 0; // 变量i从这里开始定义
...
{
...
int x = 1; // 变量x从这里开始定义
...
{
...
String s = "hello"; // 变量s从这里开始定义
...
} // 变量s作用域到此结束
...
// 注意,这是一个新的变量s,它和上面的变量同名,
// 但是因为作用域不同,它们是两个不同的变量:
String s = "hi";
...
} // 变量x和s作用域到此结束
...
} // 变量i作用域到此结束
整数运算
注意:
(1)整数的除法对于除数为0时运行时将报错,但编译不会报错。
(2)两个整数相除只能得到结果的整数部分。
移位运算
左移:
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912
右移:
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1; // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2; // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3; // 00000000 00000000 00000000 00000000 = 0
无符号的右移:
它的特点是不管符号位,右移后高位总是补0
,因此,对一个负数进行>>>
右移,它会变成正数,原因是最高位的1
变成了0
int n = -536870912;
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1
注意:
对byte和short类型进行移位时,会首先转换为int再进行位移。
左移实际上就是不断地×2,右移实际上就是不断地÷2。
与:&
或:|
非:~
异或:^
(两个数不同为1
,相同为0
)
浮点数运算
浮点数运算和整数运算相比,只能进行加减乘除这些数值计算,不能做位运算和移位运算。
public class Main {
public static void main(String[] args) {
double x = 1.0 / 10;
double y = 1 - 9.0 / 10;
// 观察x和y是否相等:
System.out.println(x);
System.out.println(y);
}
}
0.1
0.09999999999999998
如果参与运算的两个数其中一个是整型,那么整型可以自动提升到浮点型
由于浮点数存在运算误差,所以比较两个浮点数是否相等常常会出现错误的结果。正确的比较方法是判断两个浮点数之差的绝对值是否小于一个很小的数
// 比较x和y是否相等,先计算其差的绝对值:
double r = Math.abs(x - y);
// 再判断绝对值是否足够小:
if (r < 0.00001) {
// 可以认为相等
} else {
// 不相等
}
如果要进行四舍五入,可以对浮点数加上0.5再强制转型:
public class Main {
public static void main(String[] args) {
double d = 2.6;
int n = (int) (d + 0.5);
System.out.println(n);
}
}
3
布尔运算
字符和字符串
在Java中,字符和字符串是两个不同的类型。
字符类型char
是基本数据类型,字符串类型String
是引用类型,我们用双引号"..."
表示字符串。一个字符串可以存储0个到任意个字符。
字符串连接
Java的编译器对字符串做了特殊照顾,可以使用+连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。
public class Main {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "World";
String s = s1 + ' ' + s2 + '!';
System.out.println(s);
}
}
Hello World!
多行字符串
从Java 13开始,字符串可以用"""..."""
表示多行字符串(Text Blocks)了。
public class Main {
public static void main(String[] args) {
String s = """
I
am
a
beautiful
girl
""";
System.out.println(s);
}
}
I
am
a
beautiful
girl
//最后一行相当于\n ,若不想要,就将"""放到girl末尾。
字符串不变性
public class Main {
public static void main(String[] args) {
String s = "hello";
String t = s;
s = "world";
System.out.println(t); // t是"hello"还是"world"?
}
}
hello
注意
基本类型的变量是“持有”某个数值,引用类型的变量是“指向”某个对象
数组类型
定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[]
。和单个基本类型变量不同,数组变量初始化必须使用new int[5]
表示创建一个可容纳5个int
元素的数组。
Java的数组有几个特点:
(1)数组所有元素初始化为默认值,整型都是0
,浮点型是0.0
,布尔型是false
;
(2)数组一旦创建后,大小就不可改变。
public class Main {
public static void main(String[] args) {
int[] ns = new int[3];
ns[0] = 1; //赋值语句
ns[1] = 2;
ns[2] = 13;
int[] nd = new int[]{1,2,3,4}; //不要写成int nd = new int[]{1,2,3,4};
int[] nm = { 5, 6, 7, 8};
System.out.println(ns[0]);
System.out.println(ns.length); //获取数组大小
System.out.println(nd.length); //由编译器自动推算数组大小
System.out.println(nm.length);
}
}
1
3
4
4
注意:
容易想错:
public class Main {
public static void main(String[] args) {
String[] names = {"ABC", "XYZ", "zoo"};
String s = names[1];
names[1] = "cat";
System.out.println(s); // s是"XYZ"还是"cat"?
}
}
XYZ
小结:
数组是同一数据类型的集合,数组一旦创建后,大小就不可变;
可以通过索引访问数组元素,但索引超出范围将报错;
数组元素可以是值类型(如int)或引用类型(如String),但数组本身是引用类型;
第五章 流程控制
输入和输出
输出
println
是print line的缩写,表示输出并换行。如果输出后不想换行,可以用print()
。
格式化输出:
public class Main {
public static void main(String[] args) {
double d = 12700000;
System.out.println(d);
}
}
1.27E7
如果要把数据显示成我们期望的格式,就需要使用格式化输出的功能。格式化输出使用System.out.printf()
,通过使用占位符%?
,printf()
可以把后面的参数格式化成指定格式:
public class Main {
public static void main(String[] args) {
double d = 3.1415926;
System.out.printf("%.2f",d);
}
}
3.14
注意不能用System.out.println("%.2f",d);
,会报错。
例子:把一个整数格式化成十六进制,并用0补足8位
public class Main {
public static void main(String[] args) {
int n = 12345000;
System.out.printf("n = %d ,h = %08x ,h = %06x",n,n,n);
}
}
n = 12345000 ,h = 00bc5ea8 ,h = bc5ea8
输入
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("Input your name: "); // 打印提示
String name = scanner.nextLine(); // 读取一行输入并获取字符串
System.out.print("Input your age: "); // 打印提示
int age = scanner.nextInt(); // 读取一行输入并获取整数
System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
}
}
首先,通过
import
语句导入java.util.Scanner
,import
是导入某个类的语句,必须放到Java源代码的开头
然后,创建Scanner
对象并传入System.in
。System.out
代表标准输出流,而System.in
代表标准输入流。直接使用System.in
读取用户输入虽然是可以的,但需要更复杂的代码,而通过Scanner
就可以简化后续的代码。
有了Scanner
对象后,要读取用户输入的字符串,使用scanner.nextLine()
,要读取用户输入的整数,使用scanner.nextInt()
。Scanner
会自动转换数据类型,因此不必手动转换。
练习:请帮小明同学设计一个程序,输入上次考试成绩(int)和本次考试成绩(int),然后输出成绩提高的百分比,保留两位小数位(例如,21.75%)。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int score1;
int score2;
Scanner scanner = new Scanner(System.in);
System.out.println("Please input last score:"); //`println`可以自己空行,而`printf`则不空行
score1 = scanner.nextInt();
System.out.println("Please input this score:");
score2 = scanner.nextInt();
float up = (float)(score2 - score1)/score1 * 100 ;
System.out.printf("up:%.2f",up);
}
}
Please input last score:
70
Please input this score:
80
up:14.29
小结:
(1)Java提供的输出包括:System.out.println()
/ print()
/ printf()
,其中printf()可以格式化输出;
(2)Java提供Scanner对象来方便输入,读取对应的类型可以使用:scanner.nextLine()
/ nextInt()
/ nextDouble()
/ …
if判断
if
和if...else...
的用法:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int n = 90;
if (n >= 90){
System.out.println("great");
}else{
System.out.println("end");
}
}
}
great
if...else if...
的用法:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int n = 75;
if (n >= 80){ //n >= 80为true
System.out.println("A");
}else if(n >= 70){ //n >= 80为false & n >= 70为true
System.out.println("B");
}else if(n >= 60){ //n >= 70为false & n >= 60为true
System.out.println("C");
}else{ //n >= 60为false
System.out.println("D");
}
B
注意:
判断范围从大到小依次进行 且 注意边界条件
因为浮点数在计算机中常常无法精确表示,并且计算可能出现误差,因此,判断浮点数相等用==
判断不靠谱。正确的方法是利用差值小于某个临界值来判断:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double x = 1 - 9.0 /10;
if (Math.abs(x - 0.1) < 0.0001){
System.out.println("x is 0.1");
}else{
System.out.println("x is not 0.1");
}
}
}
x is 0.1
判断引用类型相等
在Java中,判断值类型的变量是否相等,可以使用==
运算符。但是,判断引用类型的变量是否相等,==
表示“引用是否相等”,或者说,是否指向同一个对象。例如,下面的两个String类型,它们的内容是相同的,但是,分别指向不同的对象,用==
判断,结果为false:
public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1);
System.out.println(s2);
if (s1 == s2) {
System.out.println("s1 == s2");
} else {
System.out.println("s1 != s2");
}
}
}
hello
hello
s1 != s2
要判断引用类型的变量内容是否相等,必须使用equals()
方法:
public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1);
System.out.println(s2);
if (s1.equals(s2)) {
System.out.println("s1 equals s2");
} else {
System.out.println("s1 not equals s2");
}
}
}
hello
hello
s1 equals s2
还可以把一定不是null
的对象"hello"
放到前面:例如:if ("hello".equals(s)) { ... }
。
练习:用if … else编写一个程序,用于计算体质指数BMI,并打印结果。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
float weight,height,BMI;
Scanner scanner = new Scanner(System.in);
System.out.printf("Please input weight:");
weight = scanner.nextFloat();
System.out.printf("Please input height:");
height = scanner.nextFloat();
BMI = weight / (height * height);
if (BMI < 18.5) {
System.out.println("Your weight is too simple");
}
else if (BMI < 25) {
System.out.println("Your weight is okey");
}else if (BMI < 28) {
System.out.println("Your weight is fat");
}else if (BMI < 32) {
System.out.println("Your weight is some fat");
}else{
System.out.println("Your weight is too fat");
}
}
}
Please input weight:56.2
Please input height:1.63
Your weight is okey
switch多重选择
根据某个表达式的结果,分别去执行不同的分支。
switch
语句根据switch (表达式)
计算的结果,跳转到匹配的case
结果,然后继续执行后续语句,直到遇到break
结束执行。
public class Main {
public static void main(String[] args) {
int option = 2;
switch(option){
case 1 :
System.out.println("Select 1");
break;
case 2 :
System.out.println("Select 2");
break;
case 3 :
System.out.println("Select 3");
break;
}
}
}
Select 2
若漏掉break
:
public class Main {
public static void main(String[] args) {
int option = 2;
switch(option){
case 1 :
System.out.println("Select 1");
case 2 :
System.out.println("Select 2");
case 3 :
System.out.println("Select 3");
}
}
}
Select 2
Select 3
- List item
因此,任何时候都不要忘记写break
和default
。
若几个case
语句执行的是同一组语句块:
public class Main {
public static void main(String[] args) {
int option = 2;
switch(option){
case 1 :
System.out.println("Select 1");
case 2 : //或者合并写成case 2,3 :
case 3 :
System.out.println("Select 2,3");
}
}
}
Select 2,3
switch
语句匹配字符串。字符串匹配时,是比较“内容相等”。
public class Main {
public static void main(String[] args) {
String fruit = "apple";
switch(fruit){
case "apple" :
System.out.println("Select apple");
break;
case "pear" :
System.out.println("Select pear");
break;
}
}
}
Select apple
switch
语句还可以使用枚举类型。
若怕遗漏break
,可使用->
,如果有多条语句,需要用{}
括起来。不要写break
语句,因为新语法只会执行匹配的语句,没有穿透效应。
public class Main {
public static void main(String[] args) {
String fruit = "pear";
switch(fruit){
case "apple" -> System.out.println("Select apple");
case "pear" ->{
System.out.println("Select pear");
System.out.println("good choice!");
}
default -> System.out.println("No fruit selected");
}
}
}
Select pear
good choice!
利用switch
赋值:
public class Main {
public static void main(String[] args) {
String fruit = "pear";
int opt = switch(fruit){
case "apple" -> 1;
case "pear" ,"mango"-> 2;
default -> 0;
}; // 注意赋值语句要以;结束
System.out.println("opt = " + opt); //注意" + "
System.out.println(opt);
}
}
opt = 2
2
yield(没看懂)
如果需要复杂的语句,我们也可以写很多语句,放到{...}
里,然后,用yield
返回一个值作为switch
语句的返回值:
public class Main {
public static void main(String[] args) {
String fruit = "orange";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> {
int code = fruit.hashCode();
yield code; // switch语句返回值
}
};
System.out.println("opt = " + opt);
}
}
opt = -1008851410
练习:使用switch
实现一个简单的石头、剪子、布游戏。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("A boy:");
String boy = scanner.nextLine();
System.out.print("A girl:");
String girl = scanner.nextLine();
switch(boy){
case "剪刀" -> {
switch(girl){
case "剪刀" -> System.out.println("draw");
case "石头" -> System.out.println("The boy sucess");
case "布" -> System.out.println("The girl sucess");
default -> System.out.println("error");
}
}
case "石头" -> {
switch(girl){
case "剪刀" -> System.out.println("The boy sucess");
case "石头" -> System.out.println("draw");
case "布" -> System.out.println("The girl sucess");
default -> System.out.println("error");
}
}
case "布" -> {
switch(girl){
case "石头" -> System.out.println("The boy sucess");
case "布" -> System.out.println("draw");
case "剪刀" -> System.out.println("The girl sucess");
default -> System.out.println("error");
}
}
default -> System.out.println("error");
}
}
}
A boy:布
A girl:剪刀
The girl sucess
while循环
while
循环在每次循环开始前,首先判断条件是否成立。如果计算结果为true
,就把循环体内的语句执行一遍,如果计算结果为false
,那就直接跳到while
循环的末尾,继续往下执行。
例如:计算1 + 2 + 3 + 4 + … + 100 = ?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int sum = 0,n = 1,m ;
Scanner scanner = new Scanner(System.in);
System.out.printf("m:");
m = scanner.nextInt();
while(n<= m) {
sum = sum + n;
n ++;
}
System.out.printf("sum = " + sum);
}
}
m:100
sum = 5050
或者:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int sum = 0,n ,m ;
Scanner scanner = new Scanner(System.in);
System.out.printf("m:");
m = scanner.nextInt();
System.out.printf("n:");
n = scanner.nextInt();
while(m <= n) {
sum = sum + m;
m ++;
}
System.out.printf("sum = " + sum);
}
}
m:1
n:100
sum = 5050
Java中的int
有最大值,达到最大值加1就会变成负数
do while循环
在Java中
while
循环是先判断循环条件,再执行循环。
do while
循环则是先执行循环,再判断条件,条件满足时继续循环,条件不满足时退出。(至少循环一次)
public class Main {
public static void main(String[] args) {
int sum = 0,n = 1;
do {
sum = sum + n;
n ++ ;
}while(n<=100);
System.out.printf("sum = " + sum);
}
}
sum = 5050
或者
public class Main {
public static void main(String[] args) {
int sum = 0,n , m;
Scanner scanner = new Scanner(System.in);
System.out.printf("n:");
n = scanner.nextInt();
System.out.printf("m:");
m = scanner.nextInt();
do {
sum = sum + n;
n ++ ;
}while(n<=m);
System.out.printf("sum = " + sum);
}
}
n:1
m:100
sum = 5050
for循环
for
循环使用计数器实现循环。先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。计数器变量通常命名为i
。
for (初始条件; 循环检测条件; 循环后更新计数器) {
// 执行语句
}
public class Main {
public static void main(String[] args) {
int[] ns = {1,4,9,16};
int sum = 0;
for(int i = 0;i < ns.length;i++) {
sum = sum + ns[i];
}
System.out.printf("sum = " + sum);
}
}
sum = 30
注意
使用for
循环时,千万不要在循环体内修改计数器
使用for
循环时,计数器变量i
要尽量定义在for
循环中
在某些情况下,是可以省略for
循环的某些语句的,但是不推荐
for each循环
可以直接遍历数组的每个元素
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16 };
for (int n : ns) {
System.out.println(n);
}
}
}
1
4
9
16
和for
循环相比,for each
循环的变量n
不再是计数器,而是直接对应到数组的每个元素。但是,for each
循环无法指定遍历顺序,也无法获取数组的索引。
除了数组外,for each
循环能够遍历所有“可迭代”的数据类型。
练习:
public class Main {
public static void main(String[] args) {
double pi = 0;
int sum = 0;
for (double i = 1;i< 9999999;i += 4) {
pi += 4/i;
pi -= 4/(i + 2);
}
System.out.println(pi);
}
}
3.1415924535897797
break和continue
break
语句通常都是配合if
语句使用。总是跳出自己所在的那一层for
循环。
break
会跳出当前循环,也就是整个循环都不会执行了。
continue
是提前结束本次循环,直接继续执行下次循环。
例如:
public class Main {
public static void main(String[] args) {
for (int i=1; i<=10; i++) {
System.out.println("i = " + i);
for (int j=1; j<=10; j++) {
System.out.println("j = " + j);
if (j >= i) {
break;
}
}
// break跳到这里
System.out.println("breaked");
}
}
}
public class Main {
public static void main(String[] args) {
int sum = 0;
for (int i=1; i<=10; i++) {
System.out.println("begin i = " + i);
if (i % 2 == 0) {
continue; // continue语句会结束本次循环
}
sum = sum + i;
System.out.println("end i = " + i);
}
System.out.println(sum); // 25
}
}
小结:
break
语句可以跳出当前循环;
break
语句通常配合if
,在满足条件时提前结束整个循环;
break
语句总是跳出最近的一层循环;
continue
语句可以提前结束本次循环;
continue
语句通常配合if
,在满足条件时提前结束本次循环。
第六章 数组操作
遍历数组
打印数组内容
直接打印数组变量,得到的是数组在JVM中的引用地址:
public class Main {
public static void main(String[] args) {
int[] ns = {1,4,9,16};
System.out.println(ns);
}
}
[I@52cc8049
Java标准库提供了Arrays.toString()
,可以快速打印数组内容:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = {1,4,9,16};
System.out.println(Arrays.toString(ns));
}
}
[1, 4, 9, 16]
数组排序
冒泡排序:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = {16,25,1,9};
for(int i = 0;i < ns.length - 1;i ++) {
for(int j = 0;j < ns.length - 1 - i;j ++) {
if(ns[j] > ns[j + 1]) {
int tmp = ns[j + 1];
ns[j + 1] = ns[j] ;
ns[j] = tmp;
}
}
}
System.out.println(Arrays.toString(ns));
}
}
[1, 9, 16, 25]
冒泡排序的特点是,每一轮循环后,最大的一个数被交换到末尾,因此,下一轮循环就可以“刨除”最后的数,每一轮循环都比上一轮循环的结束位置靠前一位。
实际上,Java的标准库已经内置了排序功能,我们只需要调用JDK提供的Arrays.sort()
就可以排序:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = {16,25,1,9};
Arrays.sort(ns);
System.out.println(Arrays.toString(ns));
}
}
小结:
(1)常用的排序算法有冒泡排序、插入排序和快速排序等;
(2)冒泡排序使用两层for循环实现排序;
(3)交换两个变量的值需要借助一个临时变量。
(4)可以直接使用Java标准库提供的Arrays.sort()
进行排序;
(5)对数组排序会直接修改数组本身。
多维数组
二维数组就是数组的数组。
二维数组的每个数组元素的长度并不要求相同,例如:
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
要打印一个二维数组,可以使用两层嵌套的for循环:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
for(int[] arr : ns) {
for(int n : arr) {
System.out.printf(n + ",");
}
}
}
}
1,2,3,4,5,6,7,8,9,
或者打印多维数组可以使用Arrays.deepToString()
:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6 },
{ 7, 8, 9 }
};
System.out.printf(Arrays.deepToString(ns));
}
}
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
三维数组:
int[][][] ns = {
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
},
{
{10, 11},
{12, 13}
},
{
{14, 15, 16},
{17, 18}
}
};
练习:使用二维数组可以表示一组学生的各科成绩,请计算所有学生的平均分:
public class Main {
public static void main(String[] args) {
int[][] scores = {
{ 82, 90, 91 },
{ 68, 72, 64 },
{ 95, 91, 89 },
{ 67, 52, 60 },
{ 79, 81, 85 },
};
double average = 0 ,sum = 0 ,total = 0;
for(int[] array : scores) {
for(int j = 0;j < array.length;j ++) {
sum += array[j] ;
total += 1;
}
}
average = sum/total;
System.out.println(average);
if (Math.abs(average - 77.733333) < 0.000001) {
System.out.println("测试成功");
} else {
System.out.println("测试失败");
}
}
}
77.73333333333333
测试成功
命令行参数
public class Main {
public static void main(String[] args) {
for (String arg : args) {
if ("-version".equals(arg)) {
System.out.println("v 1.0");
break;
}
}
}
}
(1)命令行参数类型是String[]数组;
(2)命令行参数由JVM接收用户输入并传给main方法;
理解:(参考别人的评论)
比如说Windows系统在cmd中输入 “java -version” 查看java版本,这个 “-version” 就是JVM接收用户输入的参数之后传给main方法的,然后应该是把这个参数放在public static void main(String[] args)的args这个数组里的。