这是我参与11月更文挑战的第30天,活动详情查看:2021最后一次更文挑战
希望你看到这遍文章,直呼好家伙,赶紧带给你的小伙伴们看看。
1 新人到公司启动项目要几天
这点我是深恶痛绝的,一个理想的状态应该是新人拿到电脑,装好环境,打开 IDE,导入项目,项目运行成功,如果你的项目依赖于特定的 IDE, 特定的插件版本,特殊的环境变量,这个时候你要么是文档写的明明白白,要么你就需要重新构建一下你的系统了。
2 将 Array 转换成 ArrayList 时出错
一些开发者经常用这样的代码将 Array 转化为 ArrayList
List<String> list = Arrays.asList(arr)
复制代码
Arrays.asList() 的返回值是一个 ArrayList 类的对象,这个 ArrayList 类是 Arrays 类里的一个私有静态类,并不是我们常说的那个集合 java.util.ArrayList。
java.util.Arrays.ArrayList 有 set() / get() / contains() 方法,但是并不提供任何添加元素的方法,因此它的长度是固定的。如果你希望得到一个 java.util.ArrayList 类的实例,你应该这么做:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
复制代码
ArrayList 的构造函数可以接受一个 Collection 实例,而 Collection 是 java.util.Arrays.ArrayList 的父类。
3 检查 array 里是否包含某个值时出错
一些开发者会这么写:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
复制代码
上面的代码可以工作,但是其实没必要把 list 转为 set,这有些浪费时间,简单的写法是这样的:
Arrays.asList(arr).contains(targetValue);
复制代码
或者这样的
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
复制代码
这两种写法中,前者可读性更好。
4 遍历 list 移除元素时报错
这个我们之前在 ArrayList 和 LinkedList 中的时候说过原理,这里直接上 case 。
下面的代码在迭代时移除了元素:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
复制代码
得到的结果是 [b,d]。
这种代码的问题在于,当元素被移除时,list 的长度也随之变小了,index 也同时发生了变化。所以,如果你想要在循环中使用 index 移除多个元素,它可能不能正常工作。
你可能认为在循环中删除元素的正确方法是迭代器,比如 foreach 循环看起来就是一个迭代器,其实这样还是有问题。
考虑以下代码(代码 1):
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (String s : list) {
if (s.equals("a"))
list.remove(s);
}
复制代码
会抛出 ConcurrentModificationException 异常,为什么,就是因为迭代器中有一个 Check 方法。
要正确地在遍历时删除元素,应该这么写(代码 2):
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("a")) {
iter.remove();
}
}
复制代码
你必须在每次循环里先调用 .next() 再调用 .remove()。
5 访问级别设置的过高
这点确实是,可能是为了方便,也可能是写顺手了,我们总是喜欢使用 public ,顺手写来,很少考虑这个方法/属性是否真的需要这样设置,实际上,我们应该尽可能低的设置访问级别。
6 在 switch 块中使用多个 String
这里就有点意思了,在 switch 中使用 String 不是说不行,只是太不友好,很容易出错,搞不好还会漏掉某些分支,更推荐使用的 Enum 这样保证所有人不会在 switch 中出错,而且还可以一眼看出来所有的可能分支。
7 总是使用项目定制的 StringUtils
说出这个你可能会非常惊讶,为什么会这样呢?难道我还不能自己创建一个工具类了。但是问题就是现在已经有很多成熟的 jar 可以供我们使用了,比如 Apache Commons,Google Guava,Joda Data, Hutool,这些工具难道不香嘛?你就不能稍微看一看这些优秀的开源框架嘛?