- 1、string字符串类型
- 2、常量池:
- 3、String常用方法:
------1.用引用去打点调用的方法都是实例方法!
(1)int length():可以获取字符串的长度(字符个数)
(2)String trim():去除当前字符串两边的空白字符
(3)String ①toUpperCase()/②toLowerCase():将当前字符串中的英文部分转为①全大写/②全小写
(4)char charAt(int index):返回当前字符串指定位置上的字符-------------根据下标找字符
(5)String substring(int start,int end):截取当前字符串中指定范围内的字符串(含头不含尾–包含start,但不包含end)
例:substring(2,7)————>截取2~6的范围的字符串
(6)boolean ①startsWith(String str)/②endsWith(String str):判断当前字符串是否是以给定的字符串开始的/结尾的
(7)int ①indexOf(String str)/②lastIndexOf(String str):检索给定字符串在当前字符串的开始位置/最后一次出现的位置--------根据字符串找位置
------2.用String打点访问:
(8)static String valueOf():String类中提供的静态方法,将其它数据类型转换为String - 4、String和StringBuilder的连接性能:
- 5、StringBuilder类和6种常用方法:
- 6、StringBuffer和StringBuilder区别?
API基础第一天
1、二进制
1、什么是二进制(重要)?
什么是2进制?
规则:逢二进一
数字:1 2 4 8 16 32 64
基数:2(以2为底)
权:128 64 32 16 8 4 2 1
(1)如何查看整数的2进制存储情况?
①java编译时候,会将10进制编译为2进制,然后按2进制来运算
②【例:int a = 50;】 .java(50)——>编译后——>.class(110010)
③Integer.toBinaryString()——>可以将底层的内存中2进制数显示出来
System.out.println();—————>凡是在IDEA中直接输出,都是【将2进制转换为10进制输出】
(2)①计算机为啥是2进制?——————————>便宜!成本优势明显!!!
②如何将2进制转换为10进制?————>将1位置对应的权值累加求和
注:int的二进制只能为32位:若数值开头用0b表示,显示2进制数时自动省略高位0
00000000 00000000 00000000 00000000 = 0
00000000 00000000 00000000 00000001 = 1
00000000 00000000 00000000 00000010 = 2
00000000 00000000 00000000 00000011 = 2+1 = 3
00000000 00000000 00000000 00000100 = 4
00000000 00000000 00000000 00000101 = 4+1 = 5
00000000 00000000 00000000 00000110 = 4+2 = 6
00000000 00000000 00000000 00000111 = 4+2+1=7
00000000 00000000 00000000 00001000 = 8
00000000 00000000 00000000 00001001 = 8+1=9
00000000 00000000 00000000 00001010 = 8+2=10
00000000 00000000 00000000 00001011 = 8+2+1=11
...
00000000 00000000 00000000 01101000 = 64+32+8=104
练习题:
package apiday.day03.binary;
/**
* 二进制演示 :
* 1、什么是二进制? 答:逢二进一的计数规则(重要)
* 规则:逢二进一
* 数字:1 2 4 8 16 32 64
* 基数:2(以2为底)
* 权:128 64 32 16 8 4 2 1
* 注:计算内部没有10进制,没有16进制,只有2进制!
* (1)如何查看整数的2进制存储情况?
* ①java编译时候,会将10进制编译为2进制,然后按2进制来运算
* ②【例:int a = 50;】 .java(50)——>编译后——>.class(110010)
* ③Integer.toBinaryString()——>可以将底层的内存中2进制数显示出来
* System.out.println();—————>凡是在IDEA中直接输出,都是【将2进制转换为10进制输出】
*
* (2)①计算机为啥是2进制?——————————>便宜!成本优势明显!!!
* ②如何将2进制转换为10进制?————>将1位置对应的权值累加求和
* 注:int的二进制只能为32位:若数值开头用0b表示,显示2进制数时自动省略高位0
*/
public class BinaryDemo {
public static void main(String[] args) {
int n = 50;
System.out.println(Integer.toBinaryString(n));//110010 ——>以2进制输出
System.out.println(n);//50 ——>以10进制输出
n++;//-----运行期间变量中存储的是2进制数
System.out.println(Integer.toBinaryString(n));//110011 :——>n++编译时被编译为110011——>以2进制输出
System.out.println(n);//51 ——>以10进制输出
}
}
2、补充:什么是16进制(8进制)?
什么是十六进制:
1、什么是16进制?-----16进制字面量前缀:0x
规则:逢16进1 10 11 12 13 14 15
数字:0 1 2 3 4 5 6 7 8 9 a b c d e f
基数:16(以16为底)
权:128 64 32 16 8 4 2 1
注:——————————————>计算内部没有10进制,没有16进制,只有2进制!
(1)用途:缩写2进制————>因为2进制书写非常繁琐,所以常用16进制缩写2进制
如何缩写————>将2进制从最低位开始,每4位(8421)的2进制缩写为1位的16进制
2进制: 00000000 00000000 00000000 00000000
16进制:0000 0000 0000 0000 0000 0000 0000 0000
———————————————————————————————————————————————
例1:2进制: 0100 1111 0000 0101 0111 1010 1111 1110
转为16进制:0x 4 f 0 5 7 a f e
———————————————————————————————————————————————
例2:2进制: 0110 0001 0100 1111 0111 1011 1011 1011
转为16进制:0x 6 1 4 f 7 b b b
练习题:
package apiday.day03.hex;
/**
* 十六进制演示 :
* 1、什么是16进制?-----16进制字面量前缀:0x
* 规则:逢16进1 10 11 12 13 14 15
* 数字:0 1 2 3 4 5 6 7 8 9 a b c d e f
* 基数:16(以16为底)
* 权:4096 256 16 1
* 注:——————————————>计算内部没有10进制,没有16进制,只有2进制!
* (1)用途:缩写2进制————>因为2进制书写非常繁琐,所以常用16进制缩写2进制
* 如何缩写:———>将2进制从最低位开始,每4位(8421)的2进制缩写为1位的16进制
*
* 2进制: 00000000 00000000 00000000 00000000
* 16进制:0000 0000 0000 0000 0000 0000 0000 0000
* ———————————————————————————————————————————————
* 例:
* 2进制: 0100 1111 0000 0101 0111 1010 1111 1110
* 转为16进制:0x 4 f 0 5 7 a f e
* (2)如何将16进制转为10进制?
* 答:将本身数值的数[相对应]本身数值的权的[位数][相乘]的[和]相加即为10进制
* 例1:因为16进制的权:256 16 1———>16进制【0x12】转为10进制:(1*16)+(2*1)———>即为18
* 例2:因为 8进制的权:64 8 1———>8进制【067】转为10进制:(6*8)+(7*1)——————>即为55
*
*/
public class HexDemo {
public static void main(String[] args) {
//2进制直接书写非常繁琐,16进制缩写2进制就非常方便,计算内部没有10进制,没有16进制,只有2进制!
int n = 0x4f057afe;//0x表示16进制
int m = 0b100_1111_0000_0101_0111_1010_1111_1110;//0b表示2进制---注:可以在数字中添加下划线,不影响数值
System.out.println(Integer.toBinaryString(n));//1001111000001010111101011111110
System.out.println(Integer.toBinaryString(m));//1001111000001010111101011111110
System.out.println(n);//1325759230
System.out.println(m);//1325759230
/**
* 问:将【0x12】和【0x4213】转为10进制是多少?
* 答:因为16进制的权:4096 256 16 1
* 16进制:0x12——————>转为10进制:(1*16)+(2*1)—————————————————————>即为18
* 16进制:0x4213————>转为10进制:(4*4096)+(2*256)+(1*16)+(3*1)————>即为16915
*/
int o = 0x12;
System.out.println(o);//18
System.out.println(Integer.toBinaryString(o));//10010
int p = 0x4213;
System.out.println(p);//16915
System.out.println(Integer.toBinaryString(p));//100001000010011
/**
* 补充:
* 八进制:
* 规则:逢8进1
* 数字:0 1 2 3 4 5 6 7
* 基数:8(以8为底)
* 权:8^7 8^6 8^5 8^4 472 64 8 1
*
* 问:【067】转为10进制是多少?
* 答:因为8进制的权:64 8 1
* 8进制:067—————>转为10进制:(6*8)+(7*1)—————>即为55
*/
//------小面试题:(8进制平时不用)
// int y = 068;//068编译错误,因为8进制不能出现8
int x = 067;//以数字0开始表明该数字是八进制
System.out.println(x);//55-----以10进制输出(6个8加上7个1)
System.out.println(Integer.toBinaryString(x));//110111
}
}
3、补码
计算机最底层既表示正的又表示负的,怎么表示,就画条线为补码,两边为正数和负数:
以4位2进制为例画出补码图:
补码(complement):
计算机中处理有符号数(正负数)的一种编码方式,Java中的补码最小类型是int,32位数
1、以4位2进制为例讲解补码的编码规则:-------见补码图!
(1)计算的时候如果超出4位数就自动溢出舍弃,保持4位数不变
(2)将4位2进制数分一半作为负数使用
(3)最高位称为符号位,高位为1时是负数;高位为0时是正数
2、规律数:
(1)0111为4位补码的最大值,规律:1个0和3个1,可以推导出:
--32位补码的最大值是:1个0和31个1——————>(01111111111111111111111111111111)----【一般0会省略】
(2)1000为4位补码的最小值,规律:1个1和3个0,可以推导出:
--32位补码的最小值是:1个1和31个0——————>(10000000000000000000000000000000)
(3)1111为4位补码的-1, 规律:4个1,可以推导出:
--32位补码的-1是:32个1———————————————>(11111111111111111111111111111111)
3、深入理解负值:—————> -1的编码是32个1
如何求负值:——————> 用【-1减去0对应的权值】
11111111111111111111111111111111 = -1
11111111111111111111111111111101 = -1-2 = -3
11111111111111111111111111111001 = -1-2-4 = -7
11111111111111111111111110010111 = -1-8-32-64 = -105
4、互补对称仅限于二进制补码:————————>(正数到负数对称 负数到正数对称)
验证补码的互补对称现象:一个数的补码=这个数取反+1——>公式:【-n = ~n+1】
注:~:取反(2进制表示的两个数0和1互变之后用10进制表示的数)
取反规则:0变1 1变0
例:求-3的补码? 答:-3的补码=-3取反+1————>从地球图看-3取反为2,2加1=3
-3用二进制表示:1101 -3取反用二进制表示:0010——>0010转为10进制为2——>所以2+1=3
练习题:
package apiday.day03.binary;
/**
* 补码(complement):
* 计算机中处理有符号数(正负数)的一种编码方式,Java中的补码最小类型是int,32位数
*
* 1、以4位2进制为例讲解补码的编码规则:-------见补码图!
* (1)计算的时候如果超出4位数就自动溢出舍弃,保持4位数不变
* (2)将4位2进制数分一半作为负数使用
* (3)最高位称为符号位,高位为1时是负数;高位为0时是正数
*
* 2、规律数:
* (1)0111为4位补码的最大值,规律:1个0和3个1,可以推导出:
* --32位补码的最大值是:1个0和31个1——————>(01111111111111111111111111111111)----【一般0会省略】
* (2)1000为4位补码的最小值,规律:1个1和3个0,可以推导出:
* --32位补码的最小值是:1个1和31个0——————>(10000000000000000000000000000000)
* (3)1111为4位补码的-1, 规律:4个1,可以推导出:
* --32位补码的-1是:32个1———————————————>(11111111111111111111111111111111)
*
* 3、深入理解负值:—————> -1的编码是32个1
* 如何求负值:——————> 用【-1减去0对应的权值】
* 例:
* 11111111111111111111111111111111 = -1
* 11111111111111111111111111111101 = -1-2 = -3
* 11111111111111111111111111111001 = -1-2-4 = -7
* 11111111111111111111111110010111 = -1-8-32-64 = -105
*
* 4、互补对称仅限于二进制补码:————————>(正数到负数对称 负数到正数对称)------位运算层面上的
* 验证补码的互补对称现象:一个数的补码=这个数取反+1——>公式:【-n = ~n+1】
* 注:~:取反(2进制表示的两个数0和1互变之后用10进制表示的数)
* 取反规则:0变1 1变0
* 例:求-3的补码? 答:-3的补码=-3取反+1————>从地球图看-3取反为2,2加1=3
* -3用二进制表示:1101 -3取反用二进制表示:0010——>0010转为10进制为2——>所以2+1=3
* (1)面试题
*/
public class Complement {
public static void main(String[] args) {
/** 2、规律数: */
int max = Integer.MAX_VALUE;
System.out.println(Integer.toBinaryString(max));//1111..(控制台共打印31个1)---打印时第一个1前面的0会省略
int min = Integer.MIN_VALUE;
System.out.println(Integer.toBinaryString(min));//10000000000000000000000000000000
System.out.println(Integer.toBinaryString(-1));//11111111111111111111111111111111
/** 3、深入理解负值:-1的编码是32个1 ; 如何求负值:——————> 用【-1减去0对应的权值】*/
int n = -1;
System.out.println(Integer.toBinaryString(n));//11111111111111111111111111111111
int n1 = -2;
System.out.println(Integer.toBinaryString(n1));//11111111111111111111111111111110
int n5 = -8;
System.out.println(Integer.toBinaryString(n5));//11111111111111111111111111111000
int n6 = -9;
System.out.println(Integer.toBinaryString(n6));//11111111111111111111111111110111
int n10 = -10;
System.out.println(Integer.toBinaryString(n10));//11111111111111111111111111110110
//例:将-20转为二进制如何表示?——————>-1-1-2-16————————得到下面打印的数
int n20 = -20; //32 16 8 4 2 1
System.out.println(Integer.toBinaryString(n20));//111111111111111111111111111 0 1 1 0 0
/**
* 4、面试题:
* 前面代码的运算结果是(c) 注:求100的补码
* A.-98 B.-99 C.-100 D.-101
* System.out.println(~-100+1); 注:求-100的补码
* A.98 B.99 C.100 D.101
*/
System.out.println(~100+1);//-100
System.out.println(~-100+1);//100
//例2:
int k = 6;
int l = ~n+1;
System.out.println(l);//1
int i = -3;
int j = ~i+1;
System.out.println(j);//3
}
}
2、二进制运算
01.运算符号:
~ 取反
& 与
| 或
>>> 右移位运算
>> 数学右移位运算
<< 左移位运算
02.位运算(~、&、|、>>>(>>>和>>区别)、<<)
位运算:
0、~:取反(2进制表示的两个数0和1互变之后用10进制表示的数)
(1)取反规则:0变1 1变0
1、&(与)运算(operation)-----逻辑乘法,见0则0
(1)运算规则:运算时候将两个2进制数对其位,对应位置进行与运算
例1:0 & 0 = 0 ; 0 & 1 = 0
1 & 0 = 0 ; 1 & 1 = 1
例2: 1 7 9 d 5 d 9 e
a = 00010111 10011101 01011101 10011110
f f
b = 00000000 00000000 00000000 11111111 8位掩码
c =a&b 00000000 00000000 00000000 10011110
上述代码的用途:
将a的最后8位拆分出来,存储到c中
b数称为掩码,8个1称为8位掩码
上述运算称为:掩码运算
2、|(或)运算----------------逻辑加法,见1则1
(1)运算规则:运算的时候将两个数位对齐,对应的位进行 或 运算
(2)计算的意义:上下两个数错位合并
例: ( 6 d )
a1 = 00000000 00000000 00000000 01011101
( 9 d 0 0)
b1 = 00000000 00000000 10011101 00000000
c1=a1|b1 00000000 00000000 10011101 11011101
如上案例的意义:错位合并
3、>>>(右移位)运算
(1)运算规则;将2进制数整体向右移动,低位自动溢出舍弃,高位补0
例: ( 6 7 d 7 8 6 d )
a2 = 110 01111101 01111000 01101101
b2=a2>>>1 11 00111110 10111100 00110110
c2=a2>>>2 1 10011111 01011110 00011011
(2)>>>和>>的区别:
①>>>逻辑右移位:数字向右移动,低位自动溢出,高位补0,结果没有数学意义。
如果仅仅将数位向右移动,不考虑数学意义,则使用`>>>`
②>> 数学右移位:数字向右移动,低位自动溢出,正数高位补0,负数高位补1,
移动一次数学除以,小方向取整数。如果是替代数学 /2, 使用数学右移位。
例:使用负数运算比较运算结果
n = 11111111 11111111 11111111 11001100=-1-1-2-16-32=-52
m=n>>1 11111111 11111111 11111111 11100110=-1-1-8-16=-26
k=n>>2 11111111 11111111 11111111 11110011=-1-4-8=-13
g=n>>3 11111111 11111111 11111111 11111100=-1-2-4=-7
n>>>1 01111111 11111111 11111111 11100110= max-25没有数学意义
4、<<(左移位)运算:
(1)运算规则:将2进制数整体向左移动,高位自动溢出舍弃,低位补0
5、移位在数学中的意义:
(1)>>>右移位数会变小
(2)<<左移位数会变大
例:向左移动
权 64 32 16 8 4 2 1
0 1 0 1 = 5
0 1 0 1 = 10
0 1 0 1 = 20
0 1 0 1 = 40
练习题:
package apiday.day03.operation;
/**
* 位运算:
* 0、~:取反(2进制表示的两个数0和1互变之后用10进制表示的数)
* (1)取反规则:0变1 1变0
*
* 1、&(与)运算(operation)-----逻辑乘法,见0则0
* (1)运算规则:运算时候将两个2进制数对其位,对应位置进行与运算
* 例1:0 & 0 = 0 ; 0 & 1 = 0
* 1 & 0 = 0 ; 1 & 1 = 1
* 例2: 1 7 9 d 5 d 9 e
* a = 00010111 10011101 01011101 10011110
* f f
* b = 00000000 00000000 00000000 11111111 8位掩码
* c =a&b 00000000 00000000 00000000 10011110
* 上述代码的用途:
* 将a的最后8位拆分出来,存储到c中
* b数称为掩码,8个1称为8位掩码
* 上述运算称为:掩码运算
*
* 2、|(或)运算----------------逻辑加法,见1则1
* (1)运算规则:运算的时候将两个数位对齐,对应的位进行 或 运算
* (2)计算的意义:上下两个数错位合并
* 例: ( 6 d )
* a1 = 00000000 00000000 00000000 01011101
* ( 9 d 0 0)
* b1 = 00000000 00000000 10011101 00000000
* c1=a1|b1 00000000 00000000 10011101 11011101
* 如上案例的意义:错位合并
*
* 3、>>>(右移位)运算
* (1)运算规则;将2进制数整体向右移动,低位自动溢出舍弃,高位补0
* 例: ( 6 7 d 7 8 6 d )
* a2 = 110 01111101 01111000 01101101
* b2=a2>>>1 11 00111110 10111100 00110110
* c2=a2>>>2 1 10011111 01011110 00011011
* (2)>>>和>>的区别:
* ①>>>逻辑右移位:数字向右移动,低位自动溢出,高位补0,结果没有数学意义。
* 如果仅仅将数位向右移动,不考虑数学意义,则使用`>>>`
* ②>> 数学右移位:数字向右移动,低位自动溢出,正数高位补0,负数高位补1,
* 移动一次数学除以,小方向取整数。如果是替代数学 /2, 使用数学右移位。
* 例:使用负数运算比较运算结果
* n = 11111111 11111111 11111111 11001100=-1-1-2-16-32=-52
* m=n>>1 11111111 11111111 11111111 11100110=-1-1-8-16=-26
* k=n>>2 11111111 11111111 11111111 11110011=-1-4-8=-13
* g=n>>3 11111111 11111111 11111111 11111100=-1-2-4=-7
* n>>>1 01111111 11111111 11111111 11100110= max-25没有数学意义
*
* 4、<<(左移位)运算:
* (1)运算规则:将2进制数整体向左移动,高位自动溢出舍弃,低位补0
*
* 5、移位在数学中的意义:
* (1)>>>右移位数会变小
* (2)<<左移位数会变大
* 例:向左移动
* 权 64 32 16 8 4 2 1
* 0 1 0 1 = 5
* 0 1 0 1 = 10
* 0 1 0 1 = 20
* 0 1 0 1 = 40
*
*
*/
public class operation {
public static void main(String[] args) {
/** 1、&的运算-----逻辑乘法,见0则0 */
int a = 0x179d5d9e;
System.out.println(Integer.toBinaryString(a));//10111100111010101110110011110
int b = 0xff;
System.out.println(Integer.toBinaryString(b));// 11111111
int c = a & b;
System.out.println(Integer.toBinaryString(c));// 10011110
/** 2、|的运算-----逻辑加法,见1则1 */
int a1 = 0x6d;
System.out.println(Integer.toBinaryString(a1));// 01101101
int b1 = 0x9d00;
System.out.println(Integer.toBinaryString(b1));//1001110100000000
int c1 = a1 | b1;
System.out.println(Integer.toBinaryString(c1));//1001110101101101
/** 3、>>>(右移位) */
int a2 = 0x67d786d;
int b2 = a2>>>1;
int c2 = a2>>>2;
System.out.println(Integer.toBinaryString(a2));// 0110011111010111100001101101
System.out.println(Integer.toBinaryString(b2));// 11001111101011110000110110
System.out.println(Integer.toBinaryString(c2));// 1100111110101111000011011
//(2)>>>和>>的区别:
int n = -52;//0xffffffcc;
int m = n>>1;
int k = n>>2;
int x = n>>>1;
System.out.println(Integer.toBinaryString(n));//11111111111111111111111111001100
System.out.println(Integer.toBinaryString(m));//11111111111111111111111111100110
System.out.println(Integer.toBinaryString(k));//11111111111111111111111111110011
System.out.println(Integer.toBinaryString(x));//1111111111111111111111111100110
/** 4、<<(左移位)运算 */
int a3 = 0x5e8e0dee;
int b3 = a3<<1;
int c3 = a3<<2;
System.out.println(Integer.toBinaryString(a3));// 001011110100011100000110111101110
System.out.println(Integer.toBinaryString(b3));// 010111101000111000001101111011100
System.out.println(Integer.toBinaryString(c3));//1111010001110000011011110111000
/** 5、移位在数学中的意义 */
//(1)>>>右移位数会变小
int a4 = 5;
System.out.println(a4>>>1);//2
System.out.println(a4>>>2);//1
System.out.println(a4>>>3);//0
//(2)<<左移位数会变大
int a5 = 5;
System.out.println(a5<<1);//10
System.out.println(a5<<2);//20
System.out.println(a5<<3);//40
}
}
03.将一个整数拆分为4个字节
例:
b1 b2 b3 b4
n = 00010111 10011101 01011101 10011110
b1 = 00000000 00000000 00000000 00010111
b2 = 00000000 00000000 00000000 10011101
b3 = 00000000 00000000 00000000 01011101
b4 = 00000000 00000000 00000000 10011110
代码:当n=-1;n=-3;n=max;n=min
int n = 0x179d5d9e;
int b1 = (n >>> 24) & 0xff
int b2 = (n >>> 16)& 0xff
int b3 = (n >>> 8) & 0xff;
int b4 = n & 0xff;
//验证:按照二进制输出 n b1 b2 b3 b4
//当n=-1时,按照10进制输出是啥结果?
b1 = 00000000 00000000 00000000 00010111
04.将4个字节合并为一个整数:
例:
b1 = 00000000 00000000 00000000 00010111
b2 = 00000000 00000000 00000000 10011101
b3 = 00000000 00000000 00000000 01011101
b4 = 00000000 00000000 00000000 10011110
b1<<24 00010111 00000000 00000000 00000000
b2<<16 00000000 10011101 00000000 00000000
b3<<8 00000000 00000000 01011101 00000000
b4 00000000 00000000 00000000 10011110
n = (b1<<24) | (b2<<16) | (b3<<8) | b4;
代码:
int b1 = 0x17;
int b2 = 0x9d;
int b3 = 0x5d;
int b4 = 0x9e;
int n = (b1<<24) | (b2<<16) | (b3<<8) | b4;
//按照2进制输出 b1 b2 b3 b3 n :
package apiday03;
public class Demo10 {
public static void main(String[] args) {
int b1 = 0x17;
int b2 = 0x9d;
int b3 = 0x5d;
int b4 = 0x9e;
int n = (b1<<24) | (b2<<16) | (b3<<8) | b4;
System.out.println(Integer.toBinaryString(b1));//10111
System.out.println(Integer.toBinaryString(b2));//10011101
System.out.println(Integer.toBinaryString(b3));//1011101
System.out.println(Integer.toBinaryString(b4));//10011110
System.out.println(Integer.toBinaryString(n));//10111100111010101110110011110
}
}
精华笔记:
纯底层内容,要求尽量多的吸收,能吸收多少就吸收多少,吸收不了的就放弃
1、什么是2进制:逢2进1的计数规则,计算机中的变量/常量都是按照2进制来运算的
(1)2进制:
规则:逢2进1
数字:0 1
基数:2
权:128 64 32 16 8 4 2 1
(2)如何将2进制转换为10进制:
将一个2进制数每个1位置的权值相加即可----------正数
什么是16进制:逢16进1的计数规则
2、16进制:
规则:逢16进1
数字:0 1 2 3 4 5 6 7 8 9 a b c d e f
基数:16
权:4096 256 16 1
用途:因为2进制书写太麻烦,所以常常用16进制来缩写2进制数字
如何缩写:将2进制从最低位开始,每4位2进制缩写为1位16进制
3、补码:
(1)计算机中处理有符号数(正负数)的一种编码方式,java中的补码最小类型是int,32位数
(2)以4位2进制为例讲解补码的编码规则:
计算的时候如果超出4位数就自动溢出舍弃,保持4位数不变
将4位2进制数分一半作为负数使用
最高位称为符号位,高位为1是负数,高位为0是正数
(3)深入理解负值:
记住-1的编码是32个1
负值:用-1减去0位置对应的权值
(4)互补对称:
结论:一个数的补码=这个数取反+1(取反+1) 公式: -n=~n+1
6的补码=6取反+1
-3的补码=-3取反+1
面试题:
System.out.println(~100+1); 前面代码的运算结果是(C):注:求100的补码
A.-98 B:-99 C:-100 D:-101
System.out.println(~-100+1); 前面代码的运算结果是(C): 注:求-100的补码
A.98 B:99 C:100 D:101
4、位运算:
~:取反(0变1、1变0)
&:与运算(有0则0)
|:或运算(有1则1)
:右移位运算
5、<<:左移位运算
补充:
必须掌握的:
- 什么是2进制
- 什么是16进制、16进制存在的原因
- 2进制与16进制之间的换算
1、十进制的权:
个:10的0次幂-------1
十:10的1次幂-------10
百:10的2次幂-------100
千:10的3次幂-------1000
万:10的4次幂-------10000
2、二进制的权:
2的0次幂-------1
2的1次幂-------2
2的2次幂-------4
2的3次幂-------8
2的4次幂-------16
二进制转为10进制规则:所有为1的权相加就是10进制值
例如:
权: 32 16 8 4 2 1
二进制: 1 1 0 1 0 1
十进制:32+16+4+1---------------53
API基础第二天
一、String
1、string字符串类型
字符串是常量,会保存在常量池。
注意:必须使用双引号包裹的字符串才是常量,会保存到常量池。
java语言中所有的字符都采用“单引号”括起来
java语言中所有的字符串都采用“双引号”括起来。
特点:创建之后长度内容是不可变的,每次拼接字符串,都会产生新的对象
优点:String类提供了丰富的关于操作字符串的方法,比如:拼接、获取对应下标处的字符、截取子串等等
缺点:在进行字符串拼接+=的时候,效率比较低
(1)java.lang.String使用final修饰,不能被继承
(2)java中的String在内存中采用Unicode编码方式,任何一个字符对应两个字节的编码。
(3)字符串底层封装了字符数组以及针对字符数组的操作算法
(4)字符串一旦创建,对象内容永远无法改变(因为内部是数组),但字符串引用可以重新赋值(String底层维护的是一个char[],而且String不可变,因为源码中的数组被final修饰了
)
例:
String str = new String("你好hello");//不推荐这种赋值模式
String str = "你好hello";//内存中占14个字节 共7个字符,所以占14个字节
char[] chs = {'你','好','h','e','l','l','o'} //字符串底层封装了字符数组,所以对象内容永远无法改变
2、常量池(!只有字符串才有!):
(1)java对字符串有一个优化的措施
--------------专门提供了一个字符串常量池(堆中)
。
(2)java推荐我们使用字面量/直接量的方式来创建字符串
,并且会缓存所有以字面量形式创建的字符串对象到常量池中,当使用相同字面量再次创建字符串时
会重用对象以减少内存开销
,避免内存中堆积大量内容相同的字符串对象。
例1:
String s1 = "123abc";//字符串内容是123abc----java推荐 //在常量池中存储123abc这个对象
String s2 = "123abc"//复用常量池中的123abc,不会在创建新的对象
String s3 = "123abc"//复用常量池中的123abc,不会在创建新的对象
String s5 = new String("123abc");//内存中分配了一个123abc对象----java不推荐
//在常量池中并不会缓存123abc对象
String s6 = new String("123abc");//内存中又分配了一个123abc对象
String s7 = new String("123abc");//内存中又分配了一个123abc对象
例2:
String s1 = "hello";
String s2 = "hello"
//s1和s2的地址值()是不相同的,因为存储机制是不一样的
//但我们直接使用双引号(" ")写出一个字符串时,会先在常量池查找这个字符串
//如果没有相同的则会在常量池开辟空间并创建字符串,如果有则会直接使用常量池中的字符串
例3:
package apiday.day01.string;
/**
* 一、String的演示:
* (1)java.lang.String使用的final修饰,是final的类,不能被继承
* (2)Java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的编码。
* (3)字符串底层封装了字符数组以及针对字符数组的操作算法
* (4)字符串一旦创建,对象内容永远无法改变(因为内部是数组),
* 但字符串引用可以重新赋值(String底层维护的是一个char[],而且String不可变,因为源码中的数组被final修饰了)
*
* 二、常量池(!只有字符串才有!):
* (1)java对字符串有一个优化的措施:专门提供了一个字符串常量池(堆中)。
* (2)java推荐我们使用字面量/直接量的方式来创建字符串,并且会缓存所有
* 以字面量形式创建的字符串对象到常量池中,当使用相同字面量再次创建
* 字符串时会重用对象以减少内存开销,避免**内存中堆积大量内容相同的字符串对象。
*
* 三、==和equals的区别:
* (1)==:对于基本类型而言,比较的是数值是否相等
* 对于引用类型而言,比较的是内存地址是否相等
* (2)equals:String中重写了equals(),用于比较字符串内容是否相同,
* 若不重写equals()则默认调用Object中的equals()还是比较地址,
* 所以equals()常常被重写来比较对象的数据是否相同
*/
public class StringDemo {
public static void main(String[] args) {
//例1.使用字面量创建字符串时:JVM会检查常量池中是否有该对象:
//1)若没有,则创建该字符串对象并存入常量池
//2)若有,则直接将该对象返回而不再创建一个新的字符串对象
String s1 = "123abc";//1.JVM先检查常量池是否有该对象(123abc) 1)此时还没有,就会创建一个常量池对象(123abc)
String s2 = "123abc";//2).常量池中已经有了对象,直接重用对象(123abc),不会再创建新的对象
String s3 = "123abc";//2).常量池中已经有了对象,直接重用对象(123abc),不会再创建新的对象
//注:引用类型的==,是比较的地址是否相同:
System.out.println(s1==s2);//true
System.out.println(s1==s3);//true
System.out.println(s2==s3);//true
//例2.字符串中,只要是有变量(s1)参与运算,就会开辟一个新的对象!
s1 = s1+"!";//创建新的字符串对象(:123abc!)并将地址赋值给s1--------注2:字符串连接,不在常量池中!
System.out.println(s1);//打印出:123abc!
System.out.println(s1==s2);//false,因为s1为新对象的地址,与s2不同了!
//补充:
//String字符串一旦定义好,对象内容不能再改变了,但是引用可以重新赋值
//字符串字面量会存储在字符串常量池中,当下次内容相同的字符串被使用,将直接从常量池中获取
String sss1 = "123abc";
String ss2 = new String("123abc");
String ss3 = "123"+"abc";
String s4 = sss1;
System.out.println(sss1==ss2); //false
System.out.println(sss1==ss3); //true
System.out.println(sss1==s4); //true
System.out.println(ss2==s4); //false
System.out.println(ss2.equals(s4)); //true
/*
例3.
(1)字符串中,对象参与运算,会复用常量池中的对象
(1)字符串中,只要是有变量(s1)参与运算,就会开辟一个新的对象!
String s1 = "123abc";//堆中创建一个123abc对象,常量池中存储这个对象
//编译器在编译时,若发现是两个字面量连接,
//则直接运算好并将结果保存起来,如下代码相当于String s2 = “123abc”;
String s2 = "123"+"abc";//复用常量池中的123abc对象
System.out.println(s1==s2);//true,s1与s2共用常量池中的
String s3 = "123";
//因为s3不是字面量,所以并不会直接运算结果:
String s4 = s3+"abc";//会在堆中创建新的123abc对象,而不会重用常量池中的
System.out.println(s1==s4);//false
*/
/*
常见面试题:问:在【String s = new String("hello")】中创建了几个对象?
答:2个;
第一个:字面量“hello”-------java会创建一个String对象表示字面量“hello”,并将其存入常量池。
第二个:new String()-------new String()时会再创建一个字符串,并引用hello字符串的内容。
*/
//例4:
String s = new String("hello");//s1装的是new String()对象的地址 0x1111
String ss1 = "hello";//s2装的是字面量“hello”的地址 0x2222
System.out.println("s:"+s);//s:hello
System.out.println("ss1:"+ss1);//s1:hello
System.out.println(s==ss1);//false,s和ss1内容相同但地址值不同-------注:”==“比较的是地址
//字符串实际开发中 用于比较相等的需求 都是比较字符串的内容
//因此我们应该使用字符串提供的equals()方法来比较两个字符串的内容
System.out.println(s.equals(ss1));//true,equals()比较的是内容是否相同
/*
说明:java的类都重写equals()了,
-----像:String、StringBuilder重写都比较内容了
我们自己定义的类必须自己重写equals()
*/
}
}
例1和例2面试题:
常见面试题和例4面试题:
3、String的8种常用方法:
package apiday.day01.stringmethod;
import java.util.Locale;
/**
* 《String的8种常用方法》:
* ------1.用引用去打点调用的方法都是实例方法!
* (1)int length():可以获取字符串的长度(字符个数)
* (2)String trim():去除当前字符串两边的空白字符
* (3)String ①toUpperCase()/②toLowerCase():将当前字符串中的英文部分转为①全大写/②全小写
* (4)char charAt(int index):返回当前字符串指定位置上的字符-------------根据下标找字符
* (5)String substring(int start,int end):截取当前字符串中指定范围内的字符串(含头不含尾–包含start,但不包含end)
* 例:substring(2,7)————>截取2~6的范围的字符串
* (6)boolean ①startsWith(String str)/②endsWith(String str):判断当前字符串是否是以给定的字符串开始的/结尾的
* (7)int ①indexOf(String str)/②lastIndexOf(String str):检索给定字符串在当前字符串的开始位置/最后一次出现的位置
* --------根据字符串找位置
*
* ------2.用String打点访问:
* (8)static String valueOf():String类中提供的静态方法,将其它数据类型转换为String
*
*/
public class StringMethod {
public static void main(String[] args) {
/* (1)length():可以获取字符串的长度(字符个数) */
String s = "我爱Java!";
int len = s.length();//获取str的长度
System.out.println(len);//7 即数组的长度
/* (2)trim():去除当前字符串两边的空白字符 */
String s1 = " hello world ";
System.out.println(s1);//【 hello world 】
s1 = s1.trim();
System.out.println(s1);//【hello world】
/* (3)①toUpperCase():将当前字符串中的英文部分转为全大写 */
String s6 = "我爱Java!";
String upper = s6.toUpperCase();//将s2的英文部分转换为全大写
System.out.println(upper);//我爱JAVA!
/* (3)②toLowerCase():将当前字符串中的英文部分转为全小写 */
String ss6 = "我爱java!";
upper = ss6.toLowerCase();//将ss2的英文部分转换为全小写
System.out.println(upper);//我爱java!
/* (4)charAt():返回当前字符串指定位置上的字符 */
// 0123456789012345
String s2= "thinking in Java";
char c = s2.charAt(9);//获取位置9所对应的字符串
System.out.println(c);//i
/* (5)substring(int start,int end):截取当前字符串中指定范围内的字符串(含头不含尾–包含start,但不包含end) */
// 01234567890
String s4 = "www.tedu.cn";
String name = s4.substring(4,8);//截到下标4到7范围的字符串
System.out.println(name);//tedu
//例:截取该网站的【tedu.cn】:有3种方式(注意含头不含尾)
// name = s4.substring(4,s4.length());//-----①从下边4开始一直截到末尾
// name = s4.substring(4,11);//--------------②从下边4开始一直截到末尾
name = s4.substring(4);//-------------------③从下边4开始一直截到末尾,可以默认没有
System.out.println(name);//tedu.cn
/* (6)①startsWith(String str):判断当前字符串是否是以给定的字符串开始的 */
String s7 = "I love Java";
boolean starts = s7.startsWith("I love");//判断s3是否以【I love】开头的
System.out.println(starts);//true
/* (6)②endsWith(String str):判断当前字符串是否是以给定的字符串结尾的 */
String ss7 = "123.png";
boolean ends = ss7.endsWith(".png");//判断ss3是否以【.png】结尾的
System.out.println(ends);//true
/* (7)int ①indexOf(String str):检索给定字符串在当前字符串的开始位置 */
// 01234567890
String s8 = "I love java";
int index = s8.indexOf("l");//检索【l】在字符串s8中出现的开始位置
System.out.println(index);//2
index = s8.indexOf("LO");//-----若当前字符串没有该字母,会返回【-1】
System.out.println(index);//-1
index = s8.indexOf("v",7);//从下标为2的位置开始找【lo】第一次出现的位置-------若找得到返回下标 否则返回-1
System.out.println(index);//9
/* (7)②lastIndexOf(String str):检索给定字符串在当前字符串中最后一次出现的位置 */
// 01234567890123456789
String ss8 = "I love java and Math";
int lastindex = ss8.lastIndexOf("a");//找【v】最后一次出现的位置
System.out.println(lastindex);//17
/* (8)valueOf():String类中提供的静态方法,将其它数据类型转换为String */
int a = 123;
String s9 = String.valueOf(a);//将int型变量a转换为String类型并赋值给s9
System.out.println(s9);//123-----字符串类型
double d = 123.456;
String s10 = String.valueOf(d);//将double型变量d转换为String类型并赋值给s10
System.out.println(s10);//123.456----字符串类型
String s11 = a+"";//任何内容和字符串连接的结果都是字符串,效率低
System.out.println(s11);//123-----字符串类型
}
}
案例:用indexOf()和substring()截取上边的网址中域名:
package apiday.wanke.day01;
public class LocalTest {
public static void main(String[] args) {
String name1 = "www.tedu.cn";
String name2 = "www.tarena.com.cn";
String name3 = "http://www.google.com";
String str1 = getName(name1);
System.out.println(str1);//tedu
String str2 = getName(name2);
System.out.println(str2);//tarena
String str3 = getName(name3);
System.out.println(str3);//tedugoogle
}
/**
* 案例:用indexOf()和substring()截取上边的网址中域名:
* 获取给定网址中的域名的名字 line:网址 返回域名
*/
public static String getName(String line){
//01234567890123456
//www.tarena.com.cn 域名:就是第一个点和第二个点之间的字符串
int start = line.indexOf(".")+1;//4 +1的目的是为了找到点后的第一个字符的位置
int end = line.indexOf(".",start);//10 从start往后找第一个“.”的位置
return line.substring(start,end);//含start,不含end
}
}
4、String和StringBuilder的连接性能:
(1)如下例中String类型的连接性能不好,所以Java提供了 StringBuilder解决字符串连接性能问题。
- 简单理解StringBuilder性能好!重点!
package apiday.day01.string0_0stringbuilder;
/**
* 一、String类----------------------------------方便读(String连接性能差!)
* 是不可变对象,每次修改内容都要创建新的对象,
* 因此String不适用做频繁修改动作(内存中在不断new对象),
* 为解决上面这个问题:Java提供了StringBuilder类-----方便改(用于提升String字符串的连接性能)
* ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
*
* 二、
* 1、StringBuilder类:——————是专门用于修改String的一个API
* (1)内部维护一个可变的char数组,
* (2)其API可以直接修改其内部数组的内容,
* (3)修改速度、性能优秀。
* (4)并且提供了修改字符串的常见的方法:增、删、改、插、翻转
*/
public class String0_0StringBuilderDemo {
public static void main(String[] args) {
/*
//一、测试String连接性能--------------差!
//String不适合频繁修改内容
long t1 = System.currentTimeMillis();
String s = "a";
for(int i=0;i<10000;i++){
s = s+i;
}
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//执行完for循环耗时346毫秒
System.out.println("执行完毕"+s);//执行完毕a0123...99989999
*/
//二、测试StringBuilder连接性能---------好!
long t1 = System.currentTimeMillis();
StringBuilder builder = new StringBuilder("a");
for(int i=0;i<10000;i++){
builder.append(i);
}
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//执行完for循环耗时4毫秒
System.out.println("执行完毕:"+builder);//执行完毕:a012345........99989999
}
}
5、StringBuilder类和6种常用方法:
StringBuilder类常见的方法:增、删、改、插、翻转
(1)append(int i/String str...):追加内容;当容量满了会自动扩容----括号里可包含:8种基本类型不含byte/str/[]/Obj....
注:StringBuilder的API返回的大多是当前对象,可以连续使用【.】调用方法【.append(...)】。
(2)delete(int start,int end):删除部分内容
(3)replace(int start,int end,String str):替换部分内容
(4)insert(int offset,String str):插入操作-------------------括号里第二个参可以是:8种基本类型不含byte/str/[]/Obj....
(5)reverse():将内容全部翻转
补充:toString():【便于访问时用String】和【进行增删改插翻时用StringBuilder的来回切换】。
package apiday.day01.string0_0stringbuilder;
/**
* 一、String类----------------------------------方便读(String连接性能差!)
* 是不可变对象,每次修改内容都要创建新的对象,
* 因此String不适用做频繁修改动作(内存中在不断new对象),
* 为解决上面这个问题:Java提供StringBuilder类-----方便改(用于提升String字符串的连接性能)
* ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
*
* 二、
* 1、StringBuilder类:——————是专门用于修改String的一个API
* (1)内部维护一个可变的char数组,
* (2)其API可以直接修改其内部数组的内容,
* (3)修改速度、性能优秀。
* (4)并且提供了修改字符串的常见的方法:增、删、改、插、翻转
*
* 2、StringBuilder类常见的方法:增、删、改、插、翻转
* (1)append(int i/String str...):追加内容;当容量满了会自动扩容----括号里可包含:8种基本类型不含byte/str/[]/Obj....
* 注:StringBuilder的API返回的大多是当前对象,可以连续使用【.】调用方法【.append(...)】。
* (2)delete(int start,int end):删除部分内容
* (3)replace(int start,int end,String str):替换部分内容
* (4)insert(int offset,String str):插入操作-------------------括号里第二个参可以是:8种基本类型不含byte/str/[]/Obj....
* (5)reverse():将内容全部翻转
*
* 3、toString():【便于访问时用String】和【进行增删改插翻时用StringBuilder的来回切换】。
*
* 三、StringBuffer和StringBuilder区别?
* StringBuffer:线程安全的,同步处理的,性能稍慢------不常用了
* StringBuilder:非线程安全的,并发处理的,性能稍快----经常用
*/
public class String0_0StringBuilderDemo {
public static void main(String[] args) {
/*
//一、测试String连接性能--------------差!
//String不适合频繁修改内容
long t1 = System.currentTimeMillis();
String s = "a";
for(int i=0;i<10000;i++){
s = s+i;
}
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//执行完for循环耗时346毫秒
System.out.println("执行完毕"+s);//执行完毕a0123...99989999
//二、测试StringBuilder连接性能---------好!
long t1 = System.currentTimeMillis();
StringBuilder builder = new StringBuilder("a");
for(int i=0;i<10000;i++){
builder.append(i);
}
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//执行完for循环耗时4毫秒
System.out.println("执行完毕:"+builder);//执行完毕:a012345........99989999
*/
/** 2、StringBuilder类常见的方法:增、删、改、插、翻转 */
String s = "好好学学java";
//复制str中的内容(好好学学java)到builder中
StringBuilder sb = new StringBuilder(s);
//(1)append():追加内容;当容量满了,会自动扩容
// 01 2 34 56 78
sb.append(",为了找个好工作!");
System.out.println(sb);//好好学学java,为了找个好工作!
sb.append("对不对");
System.out.println(sb);//好好学学java,为了找个好工作!对不对
//(2)delete():删除部分内容
//0 1 23 456789 0 12 3 456 78 9
//好好学学java,为了找个好工作!对不对
sb.delete(17,20);//删除下标18~20的
System.out.println(sb);//好好学学java,为了找个好工作!
//(3)replace():替换部分内容
//0 1 23 456789 0 12 3 456
//好好学学java,为了找个好工作!
sb.replace(0,16,"就是为了改变世界");//含头不含尾
System.out.println(sb);//就是为了改变世界!
//(4)insert():插入操作
sb.insert(0,"活着,");//从下标0的位置插入
System.out.println(sb);//活着,就是为了改变世界!
//(5)reverse():将内容全部翻转
sb.reverse();//翻转内容
System.out.println(sb);//!界世变改了为是就,着活
/** 3、toString():【便于访问时用String】和【进行增删改插翻时用StringBuilder的来回切换】。 */
StringBuilder builder = new StringBuilder();//空字符串
StringBuilder builder1 = new StringBuilder("abc");//abc串
System.out.println(builder1);
String str = "abc";//--------想访问用String
StringBuilder builder2 = new StringBuilder(str);//复制abc到builder2中
System.out.println(builder2);
//toString():可以将StringBuilder转换为String
String line = builder2.toString();
System.out.println(line);
/** 三、StringBuffer和StringBuilder区别?
* StringBuffer:线程安全的,同步处理的,性能稍慢------不常用了
* StringBuilder:非线程安全的,并发处理的,性能稍快----经常用
* 注:一样的东西,但是StringBuffer不常用了。
*/
StringBuffer buffer3 = new StringBuffer();
StringBuilder builder4 = new StringBuilder();
}
}
6、StringBuffer和StringBuilder区别?
StringBuffer:线程安全的,同步处理的,性能稍慢------不常用了
StringBuilder:非线程安全的,并发处理的,性能稍快----经常用
注:一样的东西,但是StringBuffer不常用了。
StringBuffer(线程安全):
StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的 增删改插 等方法可以改变这个字符串对象的字符序列。
一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。
——————————————————————————————————————————————————————————————————————————————————————
StringBuilder(非线程安全的):
StringBuilder类也代表可变字符串对象。
实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。
因为没有实现线程安全功能,所以性能略高。
补充:
1.ASCII:美国标准编码,是美国最早的字符集,也是计算机最底层的字符集,一个字节
2. GBK:国标编码,中国自己的编码,总共6万多个
3. Unicode:万国码,装全世界所有符号
4. UTF:在Unicode基础之上做的二次编码,里面加入了一个长度信息来标记是按一个字符解析还是按两个字符算
结论:互联网上真正使用的并不是unicode,真正传输出的是UTF这种带长度信息的编码,拿到UTF数据后再把长度去掉,还原成unicode编码。
5.StringBuilder和StringBuffer:
StringBuffer:是线程安全的,同步处理的,性能稍慢
StringBuilder:非线程安全的,并发处理的,性能稍快
6.getter/setter:
class Point{ //点
private int x;
private int y;
public int getX(){ //getter获取值
return x;
}
public void setX(int x){ //setter设置值
this.x = x;
}
public int getY(){
return y;
}
public void setY(int y){
this.y = y;
}
}
//getter和setter的演示
public class GetterSetterDemo {
public static void main(String[] args) {
Point p = new Point();
p.setX(100); //赋值
p.setY(200); //赋值
System.out.println(p.getX()+","+p.getY()); //取值
}
}