debug 断点调试(☆☆☆☆☆) : 虽然重要 但是 只能是后期重要。
debug : 详细查看程序的执行步骤
1:加断点 , 一般 在你要查看的程序的第一行, 左侧点一下。
2:右键 debug 程序 (不再是run)
3:左下侧 是栈, 表示现在有多少个方法进栈了, 正在执行哪个方法的哪一行。
右下侧 是方法里面的变量值。
4:下一步 F7 即可
5: 如果查看程序 查看到中间,不想看后面的了, 停止程序。
按 ctrl + F2 (红色方框按钮)
6:如果查看代码 中间有一些代码 不想看了, 相看这些代码后面的代码。
这是你就在后面的代码上 加一个断点,
按 F9 (绿色三角按钮)跳到下一个断点。
如果没有下一个断点, 程序就会立即执行完毕。
或者 alt+f9 (他需要有光标的配合, 跳到下一个光标位置)
7:程序结束之后 想把断点取消掉
如果断点少的话, 再点一下 断点的符号即可。
如果断点多的话。 ctrl+ shift + f8 (红色双原按钮)
debug 查看循环的执行流程:
for (初始化语句; 条件表达式 ; 条件控制语句 ){
语句体;
}
如果你想清楚的看到一些代码的执行顺序, 尽量把代码分成不同的行, 否则 debug就会把他当做一行代码去执行了。
int[] arr = {4,5,6,7,8};
for (int i = 0;
i < arr.length;
i++) {
System.out.println(arr[i]);
}
debug的快捷键:
1: F8 :step over 下一步下一步, 当遇到调用方法, 直接把方法当做一句话执行完毕,不会进入方法
2: F7 : step into 也是下一步的意思,但是当遇到 “自已定义的方法” 就会进入方法,把方法执行完毕之后,再回调用处继续执行。
3: alt+shift+F7 也是下一步的意思,当他遇到“源码的方法和自己定义的方法” 就会进入方法,把方法执行完毕之后,再回调用处继续执行。
4: shift+ F8 跳出方法。当进入了方法之后,不想再继续看方法里面下一步下一步怎么执行了, 想跳出方法,就按此键。
5: 想要查看表达式的结果,就可以选中表达式,右键 点击 add to watches
6: alt+ F8 如果运行过程中,你想临时的去修改一些 变量的值。你可以使用
此功能修改。 改完之后,点击 Evaluate就可以了。
位运算(☆☆☆):
进制:
几进制 就是 逢几进1, 常见的 二进制 十进制 8进制 16进制
System.out.println(99); // 99 十进制
System.out.println(0b10); //2 二进制 0b binary 二进制
System.out.println(010); // 8 八进制 0 Octal 八进制
System.out.println(0x10); // 16 十六进制 0x hex 十六进制
进制之间的转换:
其他进制转换为十进制:
十进制--> 十进制
999 = 9*10^2 + 9 *10^1 + 9*10^0 ;
其他进制-->十进制
0b111 = 1*2^2 + 1*2^1 + 1*2^0 = 4+2+1 = 7
0111 = 1*8^2 + 1*8^1 + 1*8^0 =64+8+1 = 73
0x111= 1*16^2 + 1*16^1 + 1*16^0 =256+16+1 = 273
二进制--> 快速转换--> 10进制
0b 1111 1111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255
ob 10101 = 16 +0+4+0+1 = 21
十进制转换到其他进制: 除以基 倒着取余数
十进制-->8进制
100 除以8 4
12 除以8 4
1 除以8 1
0
144
其他进制和其他进制之间的转换:
二进制 : 1111 1111
二->八进制 : 8等于2的3次方 所以三个二进制位 就是一个八进制位 011 111 111 -- 377
二->十六进制 : 16等于2的4次方 所以四个二进制位就是一个十六进制为 1111 1111 -- FF
十六进制-> 二 ab --> 1010 1011
八进制 --> 二 677 --> 110 111 111
这就是八进制和十六进制的由来:
写程序的时候在我们的程序中写代码都使用十进制。
计算机的底层 计算的时候 都是使用的二进制。
研究计算机的人 就会去竟然的去计算二进制。 但是二进制数据 你看看
1010101010101000001001111111010101010101010 --让人看得很乱。。。
原反补:
二进制: 计算机中 电子 电阻和电容。 1 0 最底层用二进制来表示的。
十进制的 10 -- 二进制 1010
十进制的 -10 --- 负数怎么表示 -1010 ??
计算机表示 负10 是绝对不会在二进制的前面加负号的, 因为计算机里面只有01
数据类型:
byte 1个字节 8个位
short 2个字节 16个位
int 4个字节 32位。
正号和符号:必须要结合着 数据类型的 最高位来去表示。
数据类型的里面 最高位 0不表示正号 1表示负号。
假设 10 和 -10 都是byte类型的。
正10 0000 1010
负10 1000 1010
byte -128 到 127
1111 1111 -127
1000 0000 -128
0000 0000 0
0111 1111 127
数据以后使用来计算的。
现在咱们来看 两个 正10相加 得到 正20吗?
0000 1010
0000 1010
--------------
0001 0100 ---- 正20
继续发现问题 如果 一个正10 加上一个 负10 会得到0吗?
0000 1010
1000 1010
-------------
1001 0100 ----- 负20
所以得到了结论, 负数的表示 不能只用高位是1
那还能怎么表示呢?
0000 1010 --- +10 这个是正10的源码。
1111 0101 --- 反码
1111 1111
+ 1
----------------
10000 0000 --- 0
1111 0101
+ 1
---------------
1111 0110 -10 这才是计算机真实底层保存的那个 -10
1000 1010 -- 原码 ---原码就是 把-10 直接按照十转二进制翻译为2进制的数据然后高位变1
1111 0101 -- 反码 ---反码就是因中间推导的过程而得名 高位不变 其他位取反。
1111 0110 -- 补码 ---补码才是负数在计算机中真实存储的数据,然后人为无法直接通过转换二进制计算出来,所以需要用过原码反码的过程推导出来。
正数的源反补都是一样的 都是 十进制直接转换二进制
0000 1010
案例1:
byte b = (byte)(100+110);
System.out.println(b); //
100+110的过程如下
00000000 00000000 00000000 01100100
+ 00000000 00000000 00000000 01101110
------------------------------------------
00000000 00000000 00000000 11010010 --- 210
byte(210) 的过程如下
00000000 00000000 00000000 11010010
11010010 -- 最高位是1 那么这个数 是 计算机真实存储的 。 这是一个 负数的补码。
- 1
--------
11010001 -- 这个负数的反码。
--------
10101110 -- 负数的源码 -- 就可以 直接二进制翻译出10进制了。 -46
案例2:
byte b = (byte)40;
System.out.println(b);
40
00000000 00000000 00000000 00101000 --40
(byte)40;
00101000 -- 高位是0 正数的原反补都是一样的。 //40
案例3:
byte b = (byte)(300+83);
300+83的过程如下:
00000000 00000000 00000001 00101100 --300
00000000 00000000 00000000 01010011 --83
-----------------------------------
00000000 00000000 00000001 01111111 --383
(byte)(383)过程如下;
00000000 00000000 00000001 01111111
01111111 -- 最高位是0 直接翻译就可以了。 127
位运算符:
& | ^ ~
和逻辑运算符的运算是基本一样的, 只不过他运算的是1和0
你就把 1当做true 把0当做false 然后进行逻辑运算。
& : 并且 有false则false 也就是有0则0
所以 一个数与0做&运算 结果是0
89 & 0 =0;
01011001
&00000000
----------
00000000
| : 或者 有true 则true 有1则1
所以 一个数 和这个数所在数据类型的最大值做或运算 结果是最大数
89 | 127 = 127
01011001
|11111111
----------
11111111
~ 没有规律
^ 有规律 异或 是否不同 不同true 相同false
一个数对另一个数异或两次 本身不变。
int a = 10 ^ 20 ^ 20 ; //10
int a = 10 ^ (20 ^ 20);
0001 0100 --20
0001 0100 --20
^
--------------
0000 0000 --0
0000 1010 --10
^0000 0000 --0
--------------
0000 1010 --10
数据交换:
1:
int a = 10;
int b = 20;
int temp = a;
a = b;
b = temp;
2:
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
3:
int a = 10;
int b = 20;
a = a+b; // a = 10+20
b = a-b; // 10+20 -20
a = a-b; // 10+20 -10
位移:
<< 左移 :(☆☆☆☆)
100 <<2
00000000 00000000 00000000 01100100
__000000 00000000 00000000 0110010000 400 =100*4
-100 << 2
10000000 00000000 00000000 01100100 这是-100的原码
11111111 11111111 11111111 10011011 反码
11111111 11111111 11111111 10011100 补码 从此处进行位运算
__111111 11111111 11111111 1001110000 补码
__111111 11111111 11111111 1001101111 反码
__100000 00000000 00000000 0110010000 原码 -400 = -100 *4
>> 有符号右移(☆☆☆☆):
100 >>2
00000000 00000000 00000000 01100100
0000000000 00000000 00000000 011001__ 25 = 100/4
-100 >> 2
0000000 00000000 00000000 01100100 这是-100的原码
11111111 11111111 11111111 10011011 反码
11111111 11111111 11111111 10011100 补码 从此处进行位运算
1111111111 11111111 11111111 100111__ 补码
1111111111 11111111 11111111 100110__ 反码
1000000000 00000000 00000000 011001__ 原码 -25 = -100/4
>>> 无符号右移(☆☆☆)。
100 >>>2
00000000 00000000 00000000 01100100
0000000000 00000000 00000000 011001__ 25 = 100/4
-100 >>> 2
0000000 00000000 00000000 01100100 这是-100的原码
11111111 11111111 11111111 10011011 反码
11111111 11111111 11111111 10011100 补码 从此处进行位运算
0011111111 11111111 11111111 100111__ 正数 不区分原反补
数组:
题目:数组反转(☆☆☆☆☆)
class Demo {
public static void main(String[] args){
int[] brr = {5,6,7,1,2,3};
reverse(brr);
for (int i =0;i<brr.length ;i++ ){
System.out.print(brr[i]+" ");
}
/*
打印结果: 3 2 1 7 6 5
*/
}
public static void reverse(int[] arr){
//补全代码
}
}
// 数组反转代码;
for (int start = 0, end = arr.length-1; start < end ;start++,end-- ){
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
二维数组(☆☆)
二维数组的由来:
数据类型
基本类型 byte short int long char boolean float double
引用类型
类 : String System Scanner Random .......
接口
数组
定义格式:
数据类型[] 变量名 = new 数据类型[数组长度];
int[] arr= new int[3];
byte[] brr = new byte[3];
引用类型数组: 类属于引用各类型 属于数据类型 符合数组的定义格式
//数据类型[] 变量名 = new 数据类型[数组长度];
Random[] arr = new Random[3];
// arr 里面可以放 3个 Random的对象
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random();
arr[0] = r1;
arr[1] = r2;
arr[2] = r3;
多维数组:属不属于引用类型,属不属于数据类型。 int[]
//数据类型[] 变量名 = new 数据类型[数组长度];
int[][] arrs = new int[2][3]; // arrs里面可以存放2个小数组 每个小数组里面存3个int值。
// 二维数组
int[][][] arrss = new int[2][3][4];
// arrss 里面可以存2个中数组 每个中数组里面存3个小数组 每个小数组里面存4个int值
//三位数组
int[][][][] arrsss = new int[2][3][4][5];
// arrsss里面 存2个大数组 每个大数组里面存3个中数组 每个中数组里面存4个小数组 每个小数组里面存5个int值。
//四维数组
//....... 多维数组
二维数组的创建:
1:态初始化
int[][] arr = new int[2][3];
arr[0] = new int[]{1,2,3,4,5,6,7,8};
int[] a = new int[5];
a[0] = 10;
arr[1] = a;
// 目前数组的值是 { {1,2,3,4,5,6,7,8} , {10,0,0,0,0} }
System.out.println(arr[1][0]); //10
arr[1][1] = 20; // 目前数组的值是 { {1,2,3,4,5,6,7,8} , {10,20,0,0,0} }
System.out.println(arr[1][1]); //20
System.out.println(arr[0][7]); //8
注意事项:
int[][] arr = new int[2][3];
arr[0] = new int[8];
arr[1] = new int[10]; // 虽然 二维数组定义规定了每一个一维数组里面是3个元素,但是 无论多个元素的一维数组都是可以赋值的。
// 虽然是直接赋值一维数组是可以的,但是 直接给一维数组赋值元素是不能超出范围的。
int[][] brr = new int[2][3];
brr[0][10] = 20; //索引越界异常
2:静态初始化
int[][] arr = {{1,2,3},{4,5,6,7},{1,2,3,4,5,6,7},{1}};
int[] a = {1,2,3};
int[] b = {4,5,6,7};
int[] c = {1,2,3,4,5,6,7};
int[] d = {1};
int[][] brr = {a,b,c,d};
//int[][][] crr = { {{1,2}, {3,4}}, {{1,2,3}, {4,5,6,7}, {8,9,10,11,12}} };
二维数组的遍历:循环的嵌套(☆☆☆☆)
int[][] arr = {{1,2,3},{4,5,6,7},{1,2,3,4,5,6,7},{1}};
/*
// 二维数组的遍历: 把每一个 int数 拿出来。
// arr[0] 是第一个一维数组
for (int i = 0; i < arr[0].length; i++) {
System.out.print(arr[0][i]+" ");
}
System.out.println();
// arr[1] 是第二个一维数组
for (int i = 0; i < arr[1].length; i++) {
System.out.print(arr[1][i]+" ");
}
System.out.println();
// arr[2] 是第三个一维数组
for (int i = 0; i < arr[2].length; i++) {
System.out.print(arr[2][i]+" ");
}
System.out.println();
// arr[3] 是第四个一维数组
for (int i = 0; i < arr[3].length; i++) {
System.out.print(arr[3][i]+" ");
}
System.out.println();
*/
for (int j = 0; j < arr.length; j++) { // 循环的嵌套
for (int i = 0; i < arr[j].length; i++) {
System.out.print(arr[j][i]+" ");
}
System.out.println();
}
二维数组的求和:
案例1:只求总和
int[][] arr = {{1,2,3},{6,7,8,5,6,8},{3,4,5,6,7,8,9}};
int sum =0;
for (int j = 0; j < arr.length; j++) {
for (int i = 0; i < arr[j].length; i++) {
sum+=arr[j][i];
}
}
System.out.println(sum);
案例2:二维数组的求总和打印出来, 每个一维数组的和 打印出来。
int sum = 0;
for (int j = 0; j < arrs.length; j++) {
int sumArr = 0;
for (int i = 0; i < arrs[j].length; i++) { //遍历一维数组
sum += arrs[j][i];
sumArr+=arrs[j][i];
}
System.out.println("第"+j+"个一位数组的和是:"+sumArr);
}
System.out.println("二维数组总和是:"+sum);
二维数组求最值:
案例1:只求总最值
int[][] arr = {{1,2,3},{4,5,6,7},{1,2,3,4,5,6,7},{10,11,12},{20,21}};
int max = arr[0][0];
for (int j = 0; j < arr.length; j++) {
for (int i = 0; i < arr[j].length; i++) {
if (arr[j][i] > max){
max = arr[j][i];
}
}
}
System.out.println(max);
案例2:只求总最值
方法一:
int[][] arr = {{1,2,3},{4,5,6,7},{1,2,3,4,5,6,7},{10,11,12},{20,21}};
int max = arr[0][0];
for (int j = 0; j < arr.length; j++) {
int smax = arr[j][0];
for (int i = 0; i < arr[j].length; i++) {
if (arr[j][i] > smax){
smax = arr[j][i];
}
if (arr[j][i] > max){
max = arr[j][i];
}
}
System.out.println("第"+j+"个数组的最大值是:"+smax);
}
System.out.println("二维数组中所有数的最大值是:"+max);
方法二:效率比方法一会高一丢丢
int[][] arr = {{1,2,3},{4,5,6,7},{1,2,3,4,5,6,7},{10,11,12},{20,21}};
int max = arr[0][0];
for (int j = 0; j < arr.length; j++) {
int smax = arr[j][0];
for (int i = 1; i < arr[j].length; i++) {
if (arr[j][i] > smax){
smax = arr[j][i];
}
}
System.out.println("第"+j+"个数组的最大值是:"+smax);
if (smax > max){
max = smax;
}
}
System.out.println("二维数组中所有数的最大值是:"+max);