本文小编为大家详细介绍“Java中不常用的开发技巧有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java中不常用的开发技巧有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
我们先来看一段代码:
BigDecimal b1= new BigDecimal(0.1); System.out.println(b1);
大家可以猜一下这个执行的结果会是什么内容呢?
结果是 0.1 么?如果不是 0.1 的话,那么执行输出的话,会出现什么内容,如果你知道,那么恭喜你,如果你不知道的话,那么就得认真学习一下拉。
结果显而易见,肯定不是 0.1 。
我们看看他的执行结果是什么内容,然后再来说,应该使用什么方式。
0.1000000000000000055511151231257827021181583404541015625
当看到这个内容的,很多人恍然大悟,一眼就看出来,精度丢失了,所以导致了这种情况的发生,成这种问题的原因是 0.1 这个数字计算机是无法精确表示的,送给 BigDecimal
的时候就已经丢精度了.double类型 那么我们应该怎么去处理这个 double
类型的参数呢?
其实很简单,方式有两种,第一种:
BigDecimal bigDecimal = new BigDecimal("0.1"); System.out.println(bigDecimal);
第二种:
BigDecimal bigDecimal1 = BigDecimal.valueOf(0.1); System.out.println(bigDecimal1);
实际上,在本质上,这两个方法并没有区别,因为。valueOf
在实现上,就是转成了一个字符串。
BigDecimal
当中的 valueOf
中是把浮点数转换成了字符串来构造的 BigDecimal
,因此避免了问题。
源码如下:
这个方法我们经常用到,用来比较 BigDecimal
的,在 BigDecimal
中使用 equals
可能会导致结果错误,BigDecimal
中提供了 compareTo
方法,在很多时候需要使用 compareTo
比较两个值。如下所示:
BigDecimal b1 = new BigDecimal("10.0"); BigDecimal b2 = new BigDecimal("10.00"); System.out.println(b1.equals(b2)); System.out.println(b1.compareTo(b2));
我们肯定遇到过这种,用 compareTo
比较的时候,自己臆想的和代码执行的,肯定不一样,于是就有了自己实验的过程。
出现此种结果的原因是,equals不仅比较了值是否相等,还比较了精度是否相同。示例中,由于两个值的精度不同,所有结果也就不相同。而 compareTo 是只比较值的大小。返回的值为-1(小于),0(等于),1(大于)。
说到 List 绝对不陌生,甚至天天在用,List 转数组,应该怎么操作呢?
其实很简单,就是 toArray。
List<String> list = new ArrayList<>(); String[] strings = list.toArray(new String[list.size()]);
两个方法,不带参数的 toArray
就是直接调用 Arrays.copyOf(elementData, size)
,将 List
中的元素对象的引用装在一个新的生成数组中。
带参数的则是会返回指定类型(必须为 List
元素类型的父类或本身)的数组对象,如果 a.length
小于 List
元素个数就直接调用 Arrays
的 copyOf()
方法进行拷贝并且返回新数组对象,新数组中也是装的 List
元素对象的引用,否则先调用System.arraycopy()
将 List
元素对象的引用装在a数组中,如果a数组还有剩余的空间,则在 a[size]
放置一个 null
,size
就是 list
中元素的个数,这个 null
值可以使得 toArray(T[] a)
方法调用者可以判断 null
后面已经没有 list
元素了.
其实在业务中,我们更多的都是直接使用第二个,第一个五参数的方法,很多时候都是作为测试来存在的。
其实了不起更想说的,还是 JDK8 中的一些肖操作,他会精简我们的代码,而且,逻辑也更加的清晰,为什么这么说,因为现在百分之八九十的公司都还是在使用 JDK8 ,升级版本的,还并不是那么的多,毕竟很少有公司会吧之前的项目随便更换某些必要的依赖的版本号,除非迫不得已。
其实这个方法,是真的不常用,因为我们用到的,很多都是 forEach
,或者 filter
,或者 map
这些都是我们比较常用的。
而 flatMap
相当于 map+flat,通过 map 把每一个元素替换为一个流,然后展开这个流。比如,我们要统计所有订单的总价格,可以有两种方式:
就是 Order 里面有一个 Detail 的信息,而这个 Order 是一个 List 而 Detail 也是一个 List,就比如下面
public class Order { private String id; private List<Detail> details; } public class Order { private String productId; private Double productPrice; private Integer productQuantity; }
如果我们想要统计订单总价,如果 Order 表中已经存在了这个价格这块的内容了,那当然好,如果没有,那么就得去汇总详情了,不是么?
//求和使用flatMap orders.stream().flatMap(order -> order.getDetails().stream()).mapToDouble(item -> item.getProductQuantity() * item.getProductPrice()).sum(); //求和使用flatMapToDouble orders.stream().flatMapToDouble(order ->order.getDetails().stream().mapToDouble(item -> item.getProductQuantity() * item.getProductPrice())).sum();
其实,了不起觉得,JDK8 中才是真的有很多了不起的内容,再比如我们统计list中的数据,已经不在需要自己去做for循环来进行比对了,而是直接通过方法来获取。
//获取最大 Integer id = userList.stream().map(User::getId).max(Integer::compareTo).get(); //获取最小 Integer id1 = userList.stream().map(User::getId).min(Integer::compareTo).get(); //获取id数量 long count = userList.stream().map(User::getId).count(); //总和 int sum = userList.stream().mapToInt(User::getId).sum(); //获取平均值 double d = userList.stream().mapToInt(User::getId).average().getAsDouble();
分组统计
//分组统计 Map<String, Long> map = userList.stream().collect(Collectors.groupingBy(User::getName, Collectors.counting())); //分组 Collectors.groupingBy(属性名) Map<Integer, List<Person>> map = list.stream().collect(Collectors.groupingBy(Person::getAge)); //将名字全转换为大写 List<String> list = userList.stream().map(User::getName).map(String::toUpperCase).collect(Collectors.toList()); //获取忽略第一个并取前几条数据 List<User> list1 = userList.stream().skip(1).limit(2).collect(Collectors.toList()); //distinct() 去重;collect(Collectors.toList())。封装成集合 List<User> collect = userList.stream().distinct().collect(Collectors.toList());
读到这里,这篇“Java中不常用的开发技巧有哪些”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。