当前位置: 代码迷 >> 综合 >> Java 常用类 03 可变字符串和BigDecimal(BigInteger)
  详细解决方案

Java 常用类 03 可变字符串和BigDecimal(BigInteger)

热度:49   发布时间:2023-11-24 12:41:26.0

3.1 可变字符串和BigDecimal


3.1.1 可变字符串

由于我们的字符串,是不可变的。每次都要在 字符串池里 新建和共享。这样效率很低,而且占用空间大。

我们的 Java 就开发了 可变字符串

下面的两者,都比传统的 String 类型要快很多。

StringBuffer:JDK1.0提供的,效率低,线程安全。

它是实现开辟一个缓冲区,然后操作的时候,直接在 缓冲区里进行操作。

StringBuilder:JDK5.0提供的,效率高,线程不安全


3.1.2 StringBuffer

append('字符串') 追加一个字符串 toString()以字符串的形式去表示

public class StringBufferAndStringBuilder {
    public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();sb.append("hello world");System.out.println(sb.toString());sb.append("java");System.out.println(sb.toString());}
}

在这里插入图片描述
insert(下标位置,插入的字符串) 可以在指定位置插入一个字符串。

replace(开始位置,终止位置,更新后的字符串) 可以替换指定范围的 字符串。切记是在 终止位置截止,即不包含终止位置。我们是替换了开始位置到终止位置-1的这个长度。


public class StringBufferAndStringBuilder {
    public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();sb.append("hello world");System.out.println(sb.toString());sb.append("java");System.out.println(sb.toString());sb.insert(0,"hahahaha:");System.out.println(sb.toString());sb.replace(0,4,"四个元素");System.out.println(sb.toString());}
}

在这里插入图片描述
delete(开始位置,终止位置) 删除指定范围的字符串。

public class StringBufferAndStringBuilder {
    public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();sb.append("hello world");System.out.println(sb.toString());sb.append("java");System.out.println(sb.toString());sb.insert(0,"hahahaha:");System.out.println(sb.toString());sb.replace(0,4,"四个元素");System.out.println(sb.toString());String string = sb.toString();System.out.println(string.contains("hello world"));System.out.println("以转换为String:"+string);sb.delete(0,sb.length());System.out.println(sb.toString());}
}

如果 想要有更多的方法操作字符串,实际上是不必的要的。因为 我们的 String 类才是字符串的 大类。这个 StringBuffer 只是起到了一定的辅助作用。当我们 配合着 来使用的时候。方可发现 基本不会缺少什么 需要的方法。

在这里插入图片描述


3.1.3 StringBuilder

StringBuidler和String Buffer的方法 一毛一样。它是底层 实现的源代码不同。提高了效率,降低了安全性。

但实际上在数据量不是很大的时候,也体现不出来。

在这里插入图片描述


3.2.1 BigDecimal(BigInteger)

大数工具类,这个工具类是非常好用的。
甚至在一些大数运算的算法题中,可以直接用这个取巧。

在面试时,我们可能会遇到HR 这样的提问。

为什么 1.0 - 0.9 = 0.09999999999999998

答:因为 用了 double 类型,表面来看,好像是精度不够导致的。但从内存的角度详细的来说,是由于 数据会存储在内存中,进而去处理和操作。当 0.9 变为二进制时。就是无限的了,根本无法得到准确的二进制。所以要用截断法。直接截取到 支持的最大精度。这样就会导致,准确的 1.0 的二进制减去了一个 不准确的 0.9 的二进制,得到了 一个更加不准确的二进制结果,然后转为 十进制输出给你。当然会是 0.09999999999999998。

那么 我们在实际开发中,如何解决这样的问题 ?

答:那我们肯定要设计一个算法了,我们都知道 四则运算 的逻辑不是很复杂,所以我们可以开辟char数组甚至是 int 数组来进行两个 运算数的各个数字。进而模拟一下四则运算得到一个最终结果即可。现如今我们也把 这样的算法 称为 大数运算。

当然了,在 JAVA 里,已经提供了这样的 类,供我们使用。那就是 BigDecimal(BigInteger)。可以很有效的解决这种问题。


3.2.1 BigDecimal 大浮点数运算类

建议大家 传递的原始 运算数以 字符串的形式来传递。因为 大数运算底层都是 字符串来搞的。这样才比较准确。

import java.math.BigDecimal;public class BigDecimalDemo {
    public static void main(String[] args) {
    double d1 = 1.0;double d2 = 0.9;System.out.println(d1 - d2);BigDecimal bd1 = new BigDecimal("1.0");BigDecimal bd2 = new BigDecimal("0.9");System.out.println(bd1.subtract(bd2));}
}

在这里插入图片描述

除法的问题,当除不尽的时候。

当除不尽的时候,我们通常都要给两个参数 传参。

 bd1.divide(bd2,2,BigDecimal.ROUND_UP);

这个的意思是,我们要保留两位小数,而且还要采取 四舍五入的模式来进行。

保留几位小数后,往往结果可能和我们想的不一样。比如说 你采取了四舍五入到小数一位。那么 1.111111 这样的数字,最后的结果反而是 1.2。而不是 1.1。但可能你现在的需求 就是得到 1.1。

解决办法:也别用其它模式了,省的复杂。直接转为字符串,对字符串进行处理即可。

import java.math.BigDecimal;public class BigDecimalDemo {
    public static void main(String[] args) {
    double d1 = 1.0;double d2 = 0.9;System.out.println(d1 - d2);BigDecimal bd1 = new BigDecimal("1.0");BigDecimal bd2 = new BigDecimal("0.9");System.out.println(bd1.subtract(bd2));System.out.println(bd1.add(bd2));System.out.println(bd1.multiply(bd2));BigDecimal bd3 = bd1.divide(bd2,2,BigDecimal.ROUND_UP);String retStr = bd3.toString();System.out.println(retStr);System.out.println(retStr.substring(0,retStr.length()-1));}
}

在这里插入图片描述

  相关解决方案