Java中不常用但很好用的开发小技巧分享
其实干Java开发必然离不开一些计算比如如果你现在工作是服务与银行那么就会对金额这些计算非常敏感所以就会经常用到BigDecimal,如果你入职的是其他行业的公司可能用的就相对没这么多今天了不起就来给大家分项一下那些不怎么常用但是非常有用的方法。BigDecimal关于BigDecimal的加减乘除了不起在这里就不再一一的去给大家说了毕竟这都是非常基础的内容我们来说说需要大家掌握的有用的方法。我们先来看一段代码12BigDecimal b1newBigDecimal(0.1);System.out.println(b1);大家可以猜一下这个执行的结果会是什么内容呢结果是 0.1 么如果不是 0.1 的话那么执行输出的话会出现什么内容如果你知道那么恭喜你如果你不知道的话那么就得认真学习一下拉。结果显而易见肯定不是 0.1 。我们看看他的执行结果是什么内容然后再来说应该使用什么方式。0.1000000000000000055511151231257827021181583404541015625当看到这个内容的很多人恍然大悟一眼就看出来精度丢失了所以导致了这种情况的发生成这种问题的原因是 0.1 这个数字计算机是无法精确表示的送给BigDecimal的时候就已经丢精度了.double类型 那么我们应该怎么去处理这个double类型的参数呢其实很简单方式有两种第一种12BigDecimal bigDecimal newBigDecimal(0.1);System.out.println(bigDecimal);第二种12BigDecimal bigDecimal1 BigDecimal.valueOf(0.1);System.out.println(bigDecimal1);实际上在本质上这两个方法并没有区别因为。valueOf在实现上就是转成了一个字符串。BigDecimal当中的valueOf中是把浮点数转换成了字符串来构造的BigDecimal因此避免了问题。源码如下compareTo这个方法我们经常用到用来比较BigDecimal的在BigDecimal中使用equals可能会导致结果错误BigDecimal中提供了compareTo方法在很多时候需要使用compareTo比较两个值。如下所示1234BigDecimal b1 newBigDecimal(10.0);BigDecimal b2 newBigDecimal(10.00);System.out.println(b1.equals(b2));System.out.println(b1.compareTo(b2));我们肯定遇到过这种用compareTo比较的时候自己臆想的和代码执行的肯定不一样于是就有了自己实验的过程。出现此种结果的原因是equals不仅比较了值是否相等还比较了精度是否相同。示例中由于两个值的精度不同所有结果也就不相同。而 compareTo 是只比较值的大小。返回的值为-1小于0等于1大于。List说到 List 绝对不陌生甚至天天在用List 转数组应该怎么操作呢其实很简单就是 toArray。toArray123ListString list newArrayList();String[] strings list.toArray(newString[list.size()]);两个方法不带参数的toArray就是直接调用Arrays.copyOf(elementData, size)将List中的元素对象的引用装在一个新的生成数组中。带参数的则是会返回指定类型必须为List元素类型的父类或本身)的数组对象如果a.length小于List元素个数就直接调用Arrays的copyOf()方法进行拷贝并且返回新数组对象新数组中也是装的List元素对象的引用否则先调用System.arraycopy()将List元素对象的引用装在a数组中如果a数组还有剩余的空间则在a[size]放置一个nullsize就是list中元素的个数这个null值可以使得toArray(T[] a)方法调用者可以判断null后面已经没有list元素了.其实在业务中我们更多的都是直接使用第二个第一个五参数的方法很多时候都是作为测试来存在的。JDK8的小玩意其实了不起更想说的还是 JDK8 中的一些肖操作他会精简我们的代码而且逻辑也更加的清晰为什么这么说因为现在百分之八九十的公司都还是在使用 JDK8 ,升级版本的还并不是那么的多毕竟很少有公司会吧之前的项目随便更换某些必要的依赖的版本号除非迫不得已。flatMap其实这个方法是真的不常用因为我们用到的很多都是forEach或者filter或者map这些都是我们比较常用的。而flatMap相当于 mapflat通过 map 把每一个元素替换为一个流然后展开这个流。比如我们要统计所有订单的总价格可以有两种方式:就是 Order 里面有一个 Detail 的信息而这个 Order 是一个 List 而 Detail 也是一个 List就比如下面1234567891011121314151617publicclassOrder {privateString id;privateListDetail details;}publicclassOrder {privateString productId;privateDouble productPrice;privateInteger productQuantity;}如果我们想要统计订单总价如果 Order 表中已经存在了这个价格这块的内容了那当然好如果没有那么就得去汇总详情了不是么123456//求和使用flatMaporders.stream().flatMap(order - order.getDetails().stream()).mapToDouble(item - item.getProductQuantity() * item.getProductPrice()).sum();//求和使用flatMapToDoubleorders.stream().flatMapToDouble(order -order.getDetails().stream().mapToDouble(item - item.getProductQuantity() * item.getProductPrice())).sum()其实了不起觉得JDK8 中才是真的有很多了不起的内容再比如我们统计list中的数据已经不在需要自己去做for循环来进行比对了而是直接通过方法来获取。12345678910//获取最大Integer id userList.stream().map(User::getId).max(Integer::compareTo).get();//获取最小Integer id1 userList.stream().map(User::getId).min(Integer::compareTo).get();//获取id数量longcount userList.stream().map(User::getId).count();//总和intsum userList.stream().mapToInt(User::getId).sum();//获取平均值doubled userList.stream().mapToInt(User::getId).average().getAsDouble();分组统计12345678910//分组统计MapString, Long map userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.counting()));//分组 Collectors.groupingBy(属性名)MapInteger, ListPerson map list.stream().collect(Collectors.groupingBy(Person::getAge));//将名字全转换为大写ListString list userList.stream().map(User::getName).map(String::toUpperCase).collect(Collectors.toList());//获取忽略第一个并取前几条数据ListUser list1 userList.stream().skip(1).limit(2).collect(Collectors.toList());//distinct() 去重collect(Collectors.toList())。封装成集合ListUser collect userList.stream().distinct().collect(Collectors.toList());关于这些不常用但是非常有用的内容你学会了么