目录
1.4 字符串:(StringBuffer-可变字符串、StringBuilder-可变字符串)
1.4.1StringBuilder和StringBuffer常见的一些方法
1、参数类型分布图
注意:
整型默认 int
浮点型默认 double
float a = 3.0;
这句话会报错,因为右边为3.0默认为double类型 double范围大 不能赋值给小范围的float
1.1 浮点型
float
double
1.1.1面试小问题 int和float 谁的精度高
结果为:int精度高
根据float的计算公式 2^(阶位-127)*数字位 阶位大于127 为整数 小于为小数
阶位=127时 2^0 ==1
阶位=128时 2^1 ==2
阶位=129时 2^2 ==4 所以float的整数排列不均匀
1.1.2使用浮点数计算存在精度丢失
理由:
主要原因是浮点数的表示方式。浮点数在计算机中以二进制形式表示,但无法准确地表示所有的实数,尤其是十进制小数。由于浮点数的表示是有限的,所以在进行浮点数计算时可能会出现精度丢失。
以下是一些导致浮点数计算精度丢失的常见原因:
-
有限的表示范围:浮点数的表示范围是有限的,取决于所使用的数据类型(如float、double等)。当超出表示范围时,浮点数会被舍入或近似表示,从而导致精度丢失。
-
二进制小数表示:浮点数在内存中以二进制表示,但某些十进制小数无法精确转换为二进制小数。例如,0.1 的十进制表示无法完全转换为有限位数的二进制表示,因此会存在舍入误差。
-
运算顺序和舍入误差累积:浮点数的运算顺序以及每次运算的舍入误差都可能导致精度丢失。由于浮点数运算是按照机器指令执行的,每次运算结果都会舍入到最接近的可表示值,这可能会引入累积的舍入误差。
-
不精确的数学运算:某些常见的数学运算,如开方、三角函数等,在浮点数计算中可能会导致精度丢失。这是因为这些运算可能需要进行多次迭代计算,并且每次计算都会引入一定的误差。
为了避免浮点数计算中的精度丢失问题,可以考虑使用其他数据类型或者采取更加精确的计算方法,例如使用BigDecimal类进行高精度计算。此外,也可以对计算过程进行适当的优化和控制,避免累积的舍入误差。
解决
java提供类
BigDecimal num1 = new BigDecimal(1.2);
BigDecimal num2 = new BigDecimal(1.2);
最后通过subtract实现计算 float res = num1 .subtract(num2 ).floatValue();
因为float存在精度丢失,进行比较时容易忽略,一般使用差值比较
1.2 字符型char
赋值方式1:char k ='d'; 单引号 一个字符
赋值方式2:char k =333; 无引号 一个字符 存放数字时 会把其当作一个抽象符号使用
赋值方式3:char p ='\u4e2d' 单引号 '\u' \u前缀
1.2.1 char大小
若编码为 ASCII 则大小为 一字节
若编码为 Unicode(java中) 则大小二字节
1.3 字符串:(String-不可变字符串)
定义之后,其值存在于字符串常量池中,jvm中专门存储常量的地方,避免创建常量时频繁的数据创建和销毁,实现数据的共享,提高系统性能。
1.3.1 Jvm内存图
类常量池:存储创建的类
栈区:方法调用(入栈出栈)
堆区,动态开辟系统空间
程序计数器:计算栈区调用方法的顺序
1.3.2 开辟空间个数注意
举例:先在类常量池中创建Test类的空间,调用时在栈区入栈main方法,在main定义变量时,创建基本数据类型aa则直接存入main中,创建引用类型String则先在字符串常量池中开辟参数空间,然后引用字符串常量池中对应参数的地址
若使用
String bb = new String(“123”)
若是String bb = new String(“123”) 则在栈区开辟new String的新空间(地址999),在main中开辟String bb的新空间,若参数值“123”以及在字符串常量池中存在,则字符串常量池中不开辟新空间,反之则开辟,然后栈区的new String在调用字符串常量池中对应参数的地址。
1.3.3 使用==时注意
== 的含义是比较地址,str3的值调用的地址是栈区的999地址的方法(如上图),而str1的值和str2的值调用的888地址,
1.3.4 字符串拼接举例
s3和s4的值相同但是两种引用的地址不同,字符串拼接实际就是(StringBuilder.toString) new String 的使用
注意两种拼接的方式:
String ss1 = “123”+”456”; 是直接寻找拼接后的结果 “123456” 如果字符串变量池中有“123456”则直接指向地址,没有再创建新的地址
1.3.5 String常见的方法
String ddd="dasddadasaaaa";
String eee="dasd";
String fff=" dasd ";
//1、获取字符串长度 length()
System.out.println(ddd.length());
//2、获取字符串中指定字符的值(代码单元)charAt()
System.out.println(ddd.charAt(0));
//3、获取字符串中指定字符的值的代码点(编码值) codePointAt()
System.out.println(ddd.codePointAt(1));
//4、字符串比较 equals() 而Object类型的参数调用equals方法是就是单纯的==比较地址
System.out.println(ddd.equals(eee));
//5、字符串裁剪substring() 要头不要尾
System.out.println(ddd.substring(0,3));
//6、查找某个子字符串所在的位置indexOf() 存在返回第一次出现的索引值 不存在返回-1
System.out.println(ddd.indexOf("dd",1));//跳过索引为1的开始找
//7、查找某个子字符串所在的位置lastIndexOf() 存在返回最后一次出现的索引值 不存在返回-1
System.out.println(ddd.lastIndexOf("a",1));//跳过索引为1的开始找
//8、是否以某个字符串开头startsWith()
System.out.println(ddd.startsWith("da"));
//9、是否以某个字符串结尾endsWith()
System.out.println(ddd.endsWith("da"));
//10、是否包含某个子串contains()
System.out.println(ddd.contains("da"));
//11、替换某个子字符串replace(),replaceAll()
System.out.println(eee.replace("d","444"));
//12、把字母全大写toUpperCase()
System.out.println(eee.toUpperCase());
//13、把字母全小写tolowerCase()
System.out.println(eee.toLowerCase());
//14、去字符串开头结尾空格trim()
System.out.println(fff);
System.out.println(fff.trim());
1.4 字符串:(StringBuffer-可变字符串、StringBuilder-可变字符串)
StringBuffer和StringBuilder的区别
1、如果不频繁修改字符串建议使用String,
2、如果频繁修改字符串,并且是多线程下建议使用StringBuffer--可以保证线程安全
3、如果频繁修改字符串,并且是单线程下建议使用StringBuilder--快 但是线程不安全
进程:计算机中最小的资源分配单位
线程:计算机中最小的执行单位
1.4.1StringBuilder和StringBuffer常见的一些方法
StringBuilder sb = new StringBuilder("asdcxzewq");
//1、添加内容
sb.append("666");//末尾添加
System.out.println(sb);
sb.insert(2,"444");//指定位置添加
System.out.println(sb);
//2、删除
sb.delete(2,6);//包括头和尾
System.out.println(sb);
sb.deleteCharAt(6);
System.out.println(sb);
//3、修改
sb.setCharAt(5,'0');
System.out.println(sb);
//4、反转
sb.reverse();
System.out.println(sb);
System.out.println(sb.charAt(0));
2、变量
2.1 变量定义
变量名必须是字母或者下划线开头,并且可由数字、字母、下划线组成,大小写敏感
变量初始化的实质是拥有自己的内存空间
2.2 变量的划分
1、全局变量(有默认值,可以不赋值)
全局变量默认值:整型:0、浮点型:0.0、 布尔型:false、 字符型:null、 引用类型:null
2、局部变量(没有默认值,使用之前一定要赋值)
3、常量
在java中,利用关键字final定义,只能被赋值一次,全局的常量必须要赋值