这次先分析分析BigDecimal的用法,因为之前自己在使用float和double这样的基本数据类型时踩过坑,所以这次写也算是有时间来看下,如何更好的看下BigDecimal的基本用法了,其基本使用还是加减乘除的运算。算是自我的一次总结吧。
先看下BigDecimal的结构图,然后在看下类的继承结构,这样便于自己进行各个方法的分析,由于这里面的方法还是蛮多的,所以分析一部分方法就可以了。
public class BigDecimal extends Number implements Comparable<BigDecimal> {}
一张图很清晰概括了这个类之间的关系,java的特性就是单继承,多实现,封装,继承,多态的完美体现了。
先看下BigDecimal类的都有哪些构造函数。太多了,先暂时看下这个方法。
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
如何将一个整数包装成BigDecimal:valueOf()方法。
public static BigDecimal valueOf(long val) {
//先判断数值是否在已定义的数组中,若在则直接返回,否则继续判断
if (val >= 0 && val < zeroThroughTen.length)
return zeroThroughTen[(int)val];
else if (val != INFLATED)
return new BigDecimal(null, val, 0, 0);
return new BigDecimal(INFLATED_BIGINT, val, 0, 0);
}
步骤一:额。这里涉及到了缓存
// Cache of common small BigDecimal values.
private static final BigDecimal zeroThroughTen[] = {
new BigDecimal(BigInteger.ZERO, 0, 0, 1),
new BigDecimal(BigInteger.ONE, 1, 0, 1),
new BigDecimal(BigInteger.valueOf(2), 2, 0, 1),
new BigDecimal(BigInteger.valueOf(3), 3, 0, 1),
new BigDecimal(BigInteger.valueOf(4), 4, 0, 1),
new BigDecimal(BigInteger.valueOf(5), 5, 0, 1),
new BigDecimal(BigInteger.valueOf(6), 6, 0, 1),
new BigDecimal(BigInteger.valueOf(7), 7, 0, 1),
new BigDecimal(BigInteger.valueOf(8), 8, 0, 1),
new BigDecimal(BigInteger.valueOf(9), 9, 0, 1),
new BigDecimal(BigInteger.TEN, 10, 0, 2),
};
这里就简单使用一下BigDecimal进行数据的加减乘除运算。
package com.wpw.springbootjuc.java8.map;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.stream.Collectors;
/**
* BigDecimal源码
*
* @author wpw
*/
@Slf4j
public class BigDecimalTest {
public static void main(String[] args) {
log.info("使用BigDecimal进行数据的输出");
BigDecimal bigDecimal = BigDecimal.valueOf(0);
System.out.println("bigDecimal = " + bigDecimal);
log.info("使用BigDecimal输出数据为10");
System.out.println(BigDecimal.TEN);
log.info("使用BigDecimal进行数据的相加");
BigDecimal a = BigDecimal.valueOf(0.06);
BigDecimal b = BigDecimal.valueOf(0.01);
System.out.println(a.add(b));
double c = 0.06d;
double d = 0.01d;
System.out.println(c + d);
log.info("使用BigDecimal进行数据的相减");
BigDecimal subtract = a.subtract(b);
System.out.println("subtract = " + subtract);
//数据精度丢失的问题
System.out.println(c - d);
log.info("使用BigDecimal进行数据的相乘");
System.out.println(a.multiply(b));
System.out.println(c * d);
log.info("使用BigDecimal进行数据的相除");
System.out.println(a.divide(b, 1, RoundingMode.HALF_UP));
System.out.println(c / d);
log.info("使用BigDecimal进行数据的比较");
System.out.println(a.compareTo(b));
//上次在写Stream流式API时,忘了总结关于数据的汇总,平均值等操作了,这里补下
List<User> userList= Lists.newArrayList();
userList.add(User.builder().build().setId(1).setName("张三").setHeight(BigDecimal.valueOf(180.00)));
userList.add(User.builder().build().setId(2).setName("李四").setHeight(BigDecimal.valueOf(180.00)));
userList.add(User.builder().build().setId(3).setName("王五").setHeight(BigDecimal.valueOf(172.00)));
log.info("汇总身高数据集合");
Optional<BigDecimal> optionalBigDecimal = userList.stream().map(User::getHeight).filter(Objects::nonNull).reduce(BigDecimal::add);
System.out.println("optionalBigDecimal.get() = " + optionalBigDecimal.get());
BigDecimal reduce = userList.stream().map(User::getHeight).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("reduce = " + reduce);
}
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Accessors(chain = true)
static class User{
private Integer id;
private String name;
private BigDecimal height;
}
}
数据的比较要使用BigDecimal的compareTo()方法进行比较,在比较两个BigDecimal是否相等时,使用compareTo()方法比较,根据返回值的正负值和零进行判断。
BigDecimal用于表示精确的小数,一般用于财务计算,因为float和double这样的类型数据在处理精度的时候会丢失,导致计算的结果不准。
0X01.统计数组中出现次数超过一半的数字,java版代码
0X02.链表中倒数第k个节点
0X03.是否是平衡树
0X04.合并两个排序的链表
0X05.从上往下打印二叉树