RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:9:30-18:00
你可能遇到了下面的问题
关闭右侧工具栏
写Java代码的一些小技巧
  • 作者:小万
  • 发表时间:2020-05-29 19:34
  • 来源:未知

  写Java代码有三年多了,遇到过很多坑,也有一些小小的心得。特地分享出来供各位学习交流。这些技巧主要涉及谷歌Guava工具类的使用、Java 8新特性的使用、DSL风格开发、代码封装等技巧。

  对于Java Developer来说空指针异常让我们深恶痛绝。我们进行单元测试的时候很多的时间就是在消除空指针异常,一个容易报空指针的代码肯定称不上是合格的代码。当然,完全消除空指针绝非易事,但我们可以最大限度地让空指针异常变得可控。只要我们知道代码何时会出现null,那么我们就成功一大半了。

  String是使用很多的类型,但是使用频繁的往往也更容易出现null的问题。

  上面这段代码有几个不确定的地方,因为id可能为null,与此同时dinNameById的方法也可能返回null,那么最后result.toUpperCase()这个方法就有可能出现空指针异常。这个问题的解决方法很简单,我稍微改进了一点代码

  我们对Id进行了null判断和empty判断,确保id是合法的。对查找的结果进行null判断,确保我们不会对null对象进行任何操作,这是因为.操作是空指针的重灾区。那么这个方法返回null这个操作是安全的吗?

  答案是安全的。显示地返回null,可以让其他人使用这个方法的时候有意地进行null判断,从而避免出现空指针的问题。还是那句话避免空指针异常并不是不使用null,而是让null变得可控。

  比如我们可以定义一个StringUtil类,里面写一个公共方法来判断null或empty。Guava工具包的Strings类已经为我们写好了,我十分建议使用稳定可靠的Guava工具类来代替自己手写的工具类。使用Guava我们只需要这样写:

  对于基本类型我们用==判断就可以,如果是String类型我们使用equals,这个是很基础的知识了。那么我们怎么判断两个对象是否相等呢?

  对于集合类的对象,我们可以遍历对象中的每个数据,逐一判断是否相等,这是简单粗暴的方式。那么如果我们判断两个class是否相等该怎么做呢?答案是用hashcode。

  这里的重点是你比较的对象必须先转成String串,然后比较String串的hashcode。因为直接比较对象的hashcode那是肯定不一样的。

  很多同学知道函数式编程很强大,也知道怎么用,但是实际应用起来总会摸不着头脑。

  只要了解了Stream的使用基本都会用它来遍历。但是什么时候用map,什么时候用forEach,这是个问题。

  其实实际项目中我们遍历一个集合类,无非是两类操作。第一种是对集合中元素的本身进行操作(如字段值的修改),第二种是消费集合中的元素,比如打印每个元素的某个值,或者让另一个方法使用元素。当然,还有第三种,就是过滤、聚合、排序,这些都是比较简单的,我们这里不谈。

  针对第一种我们应该把这种使用成为Function,这是一种给定T对象,返回R的函数式接口。详情请看我之前的文章Function接口的使用。第二种其实是Consumer,也就是消费者。这是给定T,但不返回值的函数式接口。

  这个技巧是通用的,如果你想实现什么操作,但不知道该用什么接口的时候,直接看文档就知道该用哪个接口了。

  像上面这样的场景你肯定遇到过。几个子类型,对应一个父类型,这可能有多个集合。那么如果我需要根据一个子类型,找到它对应的父类型,我就要遍历每个集合的子类型。而且由于HashMap的键不能重复,因此这种数据没有办法转成Map来操作。

  这时候我们可以调换下思路,HashMap中的键不能重复,但是值是可以重复的。我们完全可以把上面所有的子类型当做key,其父类型当做value,存储到一个Map中去。下面我使用stream来把List转为Map:

  于是所有的子类型和父类型的对应关系就都存到一个Map中去了,我们找起来就太方便了,一行代码搞定!