Top 10 Mistakes Java Developers Make

Top 10 Mistakes Java Developers Make

Reoriganize From http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/

Convert Array to ArrayList

用以下方式将数组转成ArrayList

1
List<String> list = Arrays.asList(arr);

Arrays.asList()返回的Arrays的一个内部静态类ArrayList, 而不是java.util.ArrayList. java.util.Arrays.ArrayList会有一些诸如set(), get(), contains()的方法, 但是没有任何添加元素的方法, 因为这个类是定长的. 正确的做法如下:

1
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

ArrayList 是允许接收一个集合类为参数的, 所以要把java.util.Arrays.ArrayList再通过ArrayList给构造一下.

Check If an Array Contains a Value

有人总喜欢这么做

1
2
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

但是没必要, 因为直接用也能看有无包含元素. 转成Set没有必要, 还要浪费构造开销.

1
Arrays.asList(arr).contains(targetValue);

甚至

1
2
3
4
5
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;

但第一个可读性好一点

Remove an Element from a List Inside a Loop

size会变

1
2
3
4
5
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);

迭代器异常, 会爆ConcurrentModificationException.

1
2
3
4
5
6
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));

for (String s : list) {
if (s.equals("a"))
list.remove(s);
}

正确的方式

1
2
3
4
5
6
7
8
9
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();
}
}

因为在foreach循环里, 编译器会自动将删除元素后再进行迭代器的next()操作, 这就会引起ConcurrentModificationException.异常. 可以对比一下Iterator的源码.

Hashtable vs HashMap

HashtableHashMap 最大的区别是同步化.

Use Raw Type of Collection

Java里, 原生态型(raw type)和通配符(wildcard type)可以混用. 比如 Set<?>.
但如下代码

1
2
3
4
5
6
7
8
public static void add(List list, Object o){
list.add(o);
}
public static void main(String[] args){
List<String> list = new ArrayList<String>();
add(list, 10);
String s = list.get(0);
}

会爆

1
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at ...

因为原生态型的集合类跳过了泛型检查, Set, Set<?>, 和 Set<Object> 是存在很大差别的. More details in Raw type vs. Unbounded wildcard .

Access Level

public很方便, 但是这样设计很丑陋.
如何优雅设计, 参见public, default, protected, and private.

ArrayList vs. LinkedList

LinkedList 大量删除插入, 少量随机访问
ArrayList 正好相反.

Mutable vs. Immutable

mutable通常用来避免过多的中间对象. 一个经典的例子就是大数字符串, 如果使用immutable的字符串, 那就将产生大量中间对象, 既耗空间又浪费时间, 还要垃圾立即回收.

1
2
3
4
String result="";
for(String s: arr){
result = result + s;
}

因此使用StringBuffer这种mutable的类比较合适.
more details in Why String is immutable in Java ?

Constructor of Super and Sub

!pic
父类默认构造未定义, 但是子类定义了. Java里, 一个类如果没有定义构造方法, 编译器会自动插一个无参的, 但是如果显示定义了那就不插了(这和C++不一样).
而此时子类的无参构造需要调用父类的无参构造, 但是发现不存在, 因此要报错.
要想解决这个问题, 要么给父类加一个无参的

1
2
3
public Super(){
System.out.println("Super");
}

要么把自定义的父类构造给去了, 再要么直接把super(value)塞子类构造里.

const or Constructor?

两种方式创建String

1
2
3
4
//1. use double quotes
String x = "abc";
//2. use constructor
String y = new String("abc");

但是

1
2
3
4
5
6
7
8
9
String a = "abcd";
String b = "abcd";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True

String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d); // False
System.out.println(c.equals(d)); // True

字符串直接赋值是常量, 因此都相等; 但new的时候是各自开辟空间, == 比较的是对象是否相等, 因而不等; equals比较的是值那就相等.

Leetcode -- Valid Number

Valid Number

Solve with Automata

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {

public:
inline void initPos() {
memset(pos, -1, 128);
memset(pos + 48, 1, 10);
pos['+'] = pos['-'] = 0;
pos['e'] = pos['E'] = 3;
pos['.'] = 2;
pos[' '] = 4;
}

bool isNumber(string s) {
int state = 0;
initPos();
for(char c: s)
if (!(pos[c] >= 0 && 0 <= (state = trans[state][pos[c]])))
return false;
return trans[state][5];
}

private:
// +/- d . e/E space can_accept
int trans[11][6] = {
{ 1, 2, 8, -1, 0, 0 },
{ -1, 2, 8, -1, -1, 0 },
{ -1, 2, 3, 5, 10, 1 },
{ -1, 4, -1, 5, 10, 1 },
{ -1, 4, -1, 5, 10, 1 },
{ 6, 7, -1, -1, -1, 0 },
{ -1, 7, -1, -1, 10, 0 },
{ -1, 7, -1, -1, 10, 1 },
{ -1, 9, -1, -1, -1, 0 },
{ -1, 9, -1, 5, 10, 1 },
{ -1, -1, -1, -1, 10 ,1}
};

char pos[128];
};