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

一、null的判断

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

1. String中的空指针异常

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

public String test(String id){
String result=userService.findNameById(id);
return result.toUpperCase();
}

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

public String test( String id ){
if ( id != null && !"".equals(id)){
String result = userService.findNameById( id );
if ( result != null ){
return result.toUpperCase();
}
return null;
}
return null;
}

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

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

2.使用Guava工具包的Strings类

上面的代码里我们有一行代码是这样写的

if ( id != null && !"".equals(id))

如果大量这么写的话我们会觉得十分繁琐,这种重复的工作是可以简化的。

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

if(!Strings.isNullOrEmpty(id))

比之前简单了很多吧。

二、如何判断相等

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

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

if(obj1.toString().hashCode()==obj2.toString().hashCode())

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

三、灵活使用Stream

Stream是JDK8的新特性,任何标注了@FunctionalInterface的接口都能使用Stream流来处理数据。

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

1.遍历

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

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

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



其实我们只看map里面的参数也知道,第一类的操作用map就行了。



第二种显然直接forEach就可以了。

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

四、键值对的key和value互换一下?

        List<String> DBTypes = Arrays.asList("Oracle", "SYBASE","MYSQl子对象");
List<String> JMXTypes = Arrays.asList( "消息中间件", "JBoss子对象", "Tomcat子对象", "Apache子对象");
List<String> HOSTTypes = Arrays.asList("HOST", "主机子对象");
List<String> WMITypes = Arrays.asList("Windows单进程", "Windows");

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

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

        Map<String, String> map = Maps.newHashMap();
map.putAll(DBTypes.stream().collect(Collectors.toMap(Function.identity(), i -> "JDBC")));
map.putAll(JMXTypes.stream().collect(Collectors.toMap(Function.identity(), i -> "JMX")));
map.putAll(HOSTTypes.stream().collect(Collectors.toMap(Function.identity(), i -> "HOST")));
map.putAll(WMITypes.stream().collect(Collectors.toMap(Function.identity(), i -> "WMI")));

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

   String parentType=map.get(name);

写Java代码的一些小技巧的更多相关文章

  1. IT咨询顾问:一次吐血的项目救火 java或判断优化小技巧 asp.net core Session的测试使用心得 【.NET架构】BIM软件架构02:Web管控平台后台架构 NetCore入门篇:(十一)NetCore项目读取配置文件appsettings.json 使用LINQ生成Where的SQL语句 js_jquery_创建cookie有效期问题_时区问题

    IT咨询顾问:一次吐血的项目救火   年后的一个合作公司上线了一个子业务系统,对接公司内部的单点系统.我收到该公司的技术咨询:项目启动后没有规律的突然无法登录了,重新启动后,登录一断时间后又无法重新登 ...

  2. Java 性能优化手册 — 提高 Java 代码性能的各种技巧

    转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...

  3. Lombok : 让你写 Java代码像C#一样爽

    前言 我曾经是一名 .Net 开发,如今的我是一名 Java 开发者.在我享受着 Java 成熟的生态时,我常常怀念 c# 简洁的语法:自动属性.类型推断.自动初始化器 .... 鱼,我所欲也,熊掌亦 ...

  4. 关于JS里面写JAVA代码的问题

    最近做项目需要在JS脚本里面调用一个JAVA的函数得到数据,在网上查了很久,发现JS脚本里面不能写JAVA函数.只能把JS脚本里面的代码写进JSP文件里面的<script>标签内,然后写J ...

  5. 写出优质Java代码的4个技巧(转)

    http://geek.csdn.net/news/detail/238243 原文:4 More Techniques for Writing Better Java 作者:Justin Alban ...

  6. myeclipse 写java代码提示 dead code 原因

    经常使用MyEclipse要么Eclipse编辑写java程序猿代码.您可能经常会遇到一个黄色警戒线:dead code:一般程序猿遇到这些问题都会置之不理,反正也不影响程序的编译运行.对,这不是bu ...

  7. Github代码高级搜索小技巧

    Github搜索之代码搜索 可以使用下列搜索限定符的任意组合进行代码搜索 提示:通过将一连串的搜索语法添加到搜索限定符来进一步提高搜索结果的精度. ·代码搜索注意事项 由于搜索代码的复杂性,有一些搜索 ...

  8. java或判断优化小技巧

    写业务代码的时候,我们经常要做条件判断,有的时候条件判断的或判断长达20多个.reg.equals("1") || reg.equals("2") || reg ...

  9. 写出优质Java代码的4个技巧

    我们平时的编程任务不外乎就是将相同的技术套件应用到不同的项目中去,对于大多数情况来说,这些技术都是可以满足目标的.然而,有的项目可能需要用到一些特别的技术,因此工程师们得深入研究,去寻找那些最简单但最 ...

随机推荐

  1. 图论——最小生成树prim+邻接表+堆优化

    今天学长对比了最小生成树最快速的求法不管是稠密图还是稀疏图,prim+邻接表+堆优化都能得到一个很不错的速度,所以参考学长的代码打出了下列代码,make_pair还不是很会,大体理解的意思是可以同时绑 ...

  2. 【Git 使用笔记】第二部分:基本命令 和 单分支开发

    git 基本命令 git add . git commit -am "请填写你NB的备注" git fetch --all git fetch -p  //如果远程分支删除了,本地 ...

  3. Spring Data 介绍 (一)

    简介 Spring Data是什么 Spring Data是一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得对数据的访问变得方便快捷 Spring Data JPA能干什么 可以极大的 ...

  4. 2018/04/02 PHP 中的浮点数计算问题

    首先抛出一个问题 var_dump((0.1 + 0.2) == 0.3); 这个判断是否正确呢? 它的输出是 false 是否和你想的一样呢? -- 浮点精度运算可以说是每个语言都必有的问题.因为这 ...

  5. Python 标准输出 sys.stdout 重定向

    本文环境:Python 2.7 使用 print obj 而非 print(obj) 一些背景 sys.stdout 与 print 当我们在 Python 中打印对象调用 print obj 时候, ...

  6. HTML5 web 存储

    简介: HTML5 web 存储,一个比cookie更好的本地存储方式. 首先我们先了解一下: 什么是 HTML5 Web 存储? 使用html5可以在本地存储用户的浏览数据. 早些时候,本地存储使用 ...

  7. java 原子类

    一.基本类原子操作 AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference<V>对boolean,Integer,long,refer ...

  8. JAVA包装类介绍(一)(包装类、基本类型数据)

     1. 包装类把基本类型数据转换为对象      1.1每个基本类型在java.lang包中都有一个相应的包装类  2.包装类有何作用 2.1 提供了一系列实用的方法 2.2集合不允许存放基本数据类型 ...

  9. redhat7:用户、组和权限

    用户: 任何用户被分配一个独特的用户id号(UID)  (UID 0标识root用户    用户账号通常从UID 1000开始(在redhat6及之前的版本,从500开始))  . 用户名和UID信息 ...

  10. vue学习之node.js

    Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.本文详细介绍了No ...