https://www.bilibili.com/read/cv24091867/
break label
虽然,很多人不喜欢goto语句,但是实际上,适当使用goto语句反而有益于程序的设计风格
java将goto语句作为保留字,同时设计了一种break语句来致敬goto语句 break label语句
label:{
while(...) {
...
break label;
}
}
当执行break语句的时候,其会跳出整个label标签所指代的代码块
也就是,break label可以一次性跳出一整个代码块,而不是像普通break一样只跳出一层
实际上,break label语句,并不一定用在循环结构中,只要是想跳出代码块就都可以使用break label语法,即使是在if语句中
label:{
if(...) {
...
break label;
}
}
注意,break label语句只能从一个语句块中跳出来,而不能跳入一个语句块中
continue
continue语句也会中断正常的控制流程。其会将控制转移到最内层循环的首部。
continue语句也有一种带标签的写法。其可以跳到与标签匹配的循环的首部
java.math 包中有两个有用的类:
BigInteger类:
可以实现任意精度的整数运算
BigDecimal类:
可以实现任意精度的浮点数运算
上述的两个类,对数字的长度都没有要求(随便给多长都可以)
这两个类都提供了静态方法 valueOf() 可以将普通的字面值转换为大数类型
BigInteger a = BigInteger.valueOf(100);
但是非常可惜,java中没有提供C++类似的运算符号重载功能(只对String类型设计了+连接运算),不可以使用 +,*等运算符号作用在实例上,只能使用类中定义好的add和multiply等方法。
BigInteger a = BigInteger.valueOf(100);
a = a.add(BigInteger.valueOf(2)).divide(BigInteger.valueOf(2));
// a = (a + 2) / 3
// 连续使用.运算符去多次连续调用方法?
提供的方法有:
BigInteger add(BigInteger other) +
BigInteger subtract(BigInteger other) -
BigInteger multiply(BigInteger other) *
BigInteger divide(BigInteger other) /
BigInteger mod(BigInteger other) %
int compareTo(BigInteger other) 提供了一个比较方法,等于返回0,大于返回+,小于返回-
static BigInteger valueOf(long x) 返回值等于x的一个大整数类的实例
BigDecimal类中提供的方法大体相似,但是,mod方法必须给定舍入方式作为第二个参数,RoundingMode.HALF_UP就是常见的四舍五入的方法
数组用来存放相同类型的数据
声明一个数组变量:
int []a;
int a[];
// 这两种方法都可以
为数组变量分配一个内存中的数组:
int []a = new int[100];
// 为数组a分配一个可以存放100个int数据的空间
数组的下标还是从0开始,如果访问a[100]会出现边界错误
数组一旦被创建,其中的元素都会被初始化:
数组一旦被创建,就不可以改变其长度,如果想要动态改变数组的长度,应该使用数组列表(Array List),可以使用 .length 属性来获得一个数组的长度
for-each循环可以不用使用下标来访问一个容器中的所有元素
语法:
for(type variable : collection) statement
其中,variable是用来暂时存放collection中的元素,collection是一个数组,或者,一个实现了Iterable的接口的类对象(Array List)也可以
可以在使用一种简化的语法来在创建一个数组对象的同时赋予初始值
// 先创建一个变量
int []a = new int[100];
// 再对变量进行初始化
// 在创建变量的同时就对其进行初始化
int []a = {
1,2,4};
在这种语法中,是不需要使用new的,在创建一个数组的同时,使用花括号中的值对数组进行初始化
Java中的[]的符号和C++不同,其被定义用来判断数组的边界。
需要注意的是,java中是允许数组的长度为0的。但是长度为0的数组不等于null。类类型变量的值为null说明,这个变量没有被分配实例。但是这里是分配了实例的,只是这个实例没有占用内存。
也可以创建一个匿名数组(我感觉,就是,之前必须先创建一个对象,再对对象进行初始化,现在可以在不指明所分配对象的前提下,先把内存分配好,同时初始化)
new int[]{
1,2,3};
// 可以用来重新初始化一个数组(其实本质上是重新分配一个)
a = new int[]{
1,2,3,5}
Java中,声明和定义的数组类似于C++中的堆栈:
int* a = new int[100];
// 这样定义的数组,内存是分配在heap(堆)上面的
int a[100];
// 这样定义的数字,内存是分配在stack(栈)上面的
// 注意啊,这两种方式都不会对元素进行初始化
这个地方可以再提一下C++中的动态数组和静态数组
静态数组在栈上创建,同时具有自动存储期期限。不需要我人为去管理数组的内存。他们在自己的作用域外就会被销毁。同时静态数组在编译的时候会固定其大小,之后就不能再改变了。
int array[100];
动态数组具有人为可控的存储时间,存储在堆上。他们可以在任何时间被以任何大小创建(空间够的话)。但是我必须人为去在内存中定位其存储的空间,并且要手动去删除它。
int* array = new int[100];
如果直接将数组进行相互赋值,实际上,相当于只是将两个不同的指针指向了相同的一块内存区域(浅复制)
int []a = new int[]{
1,2,3,4};
int []b = a;
b[0] = 3;
// 那么,a中的第一个元素也会变成3
如果期望的复制方法是深复制,那么,就可以使用Arrays类中的方法copyOf(按元素复制,深复制)
int []a = Arrays.copyOf(a, size);
// 第一个参数是被复制的数组
// 第二个参数是复制多少个元素,如果size小于b的size,b中多余的元素会被初始化,如果大于,则只复制前面的元素
Java中的main函数的参数列表中有 String args[] 这个参数,其就是用来接受命令行中传入的参数的。
public class Message{
public static void main(String args[]) {
System.out.print(args[0]);
}
}
// java Message Hello 就会在命令行中显示Hello
和C++中不同的是,C++的命令行参数会在第一个下标的地方额外存放一下程序的名字。
Java不会存储额外的程序的名字,第一个下标就是第一个输入的参数。
对数值类型的数组可以用Arrays类中的sort方法进行排序(一个静态方法)。
int []a = new int[1000];
Arrays.sort(a);
那就是,相当于,Java中的数组传入的时候都是给的引用,所以sort方法中,对a的操作会直接体现的方面外面的a上。
Math.random方法可以返回一个从0到1之间的随机浮点数
static String toString(type[] a)
static String copyOf(type[] a)
static String copyOfRange(type[] a)
static String sort(type[] a)
static String binarySearch(type[] a, type v)
找到了就返回相应的下标值,否则就返回一个负数
static String binarySearch(type[] a, int start, int end, type v)
在一个给定的范围查找,找到了就返回相应的下标值,否则就返回一个负数r,-r-1就是如果这个数字应该在数组中出现的话,其出现的位置的下标
static void fill(type[] a, type v)
将a中的所有的元素干成v
static boolean equals(type[] a, type[] b)
检查两个数组是否相同(对应下表的元素全部都相同)
语法:
// 声明一个二维数组
double [][]a;
注意,这样只是声明了一个二维数组,其还没有被分配具体的内存空间,不可以直接使用。
初始化:
a = new double[X][Y];
也可以用一些数值来对数据进行初始化(语法更加简洁)
double [][]a = {
{
1,2}, {
3,4}};
一旦数组被初始化,就可以用两个下标来访问多维数组中的元素
System.out.print(a[1][1]);
对于一个二维数组,其中的元素是一个一维数组,所以,对一个二维数组使用for each循环,只能遍历每个行,但是如果还想要遍历每个元素,就必须再嵌套一个for each循环去遍历行中的每个元素。
for(double []t : a) {
for(double T : t) {
System.out.print(a);
}
}
使用**Arrays.deepToString()**方法可以快速将一个二维数组打印为列表形式。
实际上,Java中的是没有多维数组的机制的,其只有一维数组,多维数组被解释为数组的数组。
Java中二维数组的行是可以交换的。
double[] temp = a[1];
a[1] = a[2];
a[2] = temp;
Java中二维数组也不要求行的规模是一样的。