1. Array 转为 ArrayList
很多人会这么写:
1
|
List<String> list = Arrays.asList(arr);
|
但是要知道,虽然Arrays.asList()是这么实现的:
1
2 3 |
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a); } |
但是这里的ArrayList是Arrays的一个static 静态类,不是java.util,ArrayList
所以,应该这么写:
1
|
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
|
2. 判断是否数组里含有某个值
1
2 |
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue); |
上面的写法虽然可以工作,但是没必要转为set呀,应该这么写:
1
|
Arrays.asList(arr).contains(targetValue);
|
3. 在循环里移除List的元素
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); |
这没写是想把元素全部移走吧。但是不行哦。因为在迭代时改变被迭代对象很容易出问题。他的返回是:
1
|
[b, d]
|
当然,如果你用了for也是不行的:
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); } |
以上代码抛出ConcurrentModificationException.就是因为迭代的时候,修改被迭代对象。
应该这么写,显示得使用迭代器:
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(); } } |
4. Hashtable 和 HashMap
Hashtable和HashMap内在的算法其实是差不多的。但是他们所处于的类族不同,一个在Collection里,一个在Dictionary里。
当然,最关键是的是Hashtable是同步的,而HashMap 不是。但一般来说,你还是用HashMap 吧!
5.使用原始类型的集合
Java5开始支持了泛型,但是很多人可能都不懒得用。喜欢什么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); } |
上面的代码可以编译通过,但是在运行时会有
Exception in thread “main” java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at …
原因就是因为使用raw type,因此在编译时得不到类型检查。
6. 访问级别
不要偷懒 在属性上使用public,这样你不好控制权限。在什么时候被修改,你都不知道。
7. ArrayList vs. LinkedList
参考 吧!有详细的说明。这里不多说了。一个比较基础的问题
8. 可变和不可变
记住,String是不可变的。就是说当
1
2 3 4 |
String result="";
for(String s: arr){ result = result + s; } |
当你这么做的时候,其实你在不断的产生新的String,而不是修改同一个String。但是,JDK会在编译时做优化,把上面的代码用StringBuilder重新实现一下。具体也可以参考。
9. 子类和父类的构造函数
在Java中,一个类如果没有申明构造函数,Java会自动生成一个不带参数的构造函数。但是,如果已经声明了一个,Java就不会再生成那个构造函数了。
但是不幸的是,子类总是会调用父类的无参构造函数,所以,请一定要让父类有一个无参的构造函数,保证你编译能通过。
10. String使用””还是new
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 |
这个也不多少了,String不可变已经常量池的问题。这里注意String还有一个方法是intern(),返回常量池的引用。
我又要提了,里面有对String的说明,讲过这个问题。有兴趣的读者可以去看看。