这个列表总结了Java开发人员经常犯的10个错误. #1. Array 转换成 ArrayList 把Array转换成一个ArrayList,开发人员常常这么做: List<String> list = Arrays.asList(arr); Arrays.asList()将返回一个ArrayList,它是Arrays类里面的私有内部静态类,并不是java.util.ArrayList类。 java.util.Arrays.ArrayList类有set(),get(), contains() 这些方法,但没有任何添加元素的方法,因此它的大小是固定的。 要创建一个真正的ArrayList,你应该这样: ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr)); ArrayList构造函数可以接受一个集合类型,这个集合类型是java.util.Arrays.ArrayList的父类。 #2. 检测数组是否包含一个值 开发者一般的做法: Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue); 这段代码可以运行,但是没有必要先把一个list转成一个set。把一个list转换成一个set需要额外的时间。 它可以简单的写成这样: Arrays.asList(arr).contains(targetValue); 或者 for(String s: arr){ if(s.equals(targetValue)) return true; } return false; 第一个比第二个更具可读性。 #3. 循环中从列表中删除一个元素 考虑下面的代码,迭代中删除元素: 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] 该 方法中有一个严重的问题。当一个元素被删除,列表的大小收缩并且index也在变化。所以如果你想在循环中使用index删除多个数据,将无法正常工作。 你可能知道使用iterator在循环中删除元素是正确的方法,你也知道在java中foreach循环和iterator一样,事实上并不是这样, 考虑下面的代码: ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); } 它将抛出ConcurrentModificationException异常。 相反下面就可以: 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()方法调用之前被调用。在foreach循环中,编译器是在删除元素后调用.next(),这导致抛出 ConcurrentModificationException异常。你可能想看一下ArrayList.iterator()源代码。 #4. Hashtable vs HashMap 在算法的惯例中,HashTable 是一种数据结构的名称。但是在java中,数据结构的名称是HashMap. HashTable和HashMap最主要的区别之一是HashTable是同步的。因此,很多时候,你不需要HashTable,而是HashMap. #5. 使用原始的集合类型 在Java中,原始类型和无界通配符类型很容易混在一起。以Set集合为例,Set是原始类型,而 Set<?>是无界通配符类型。 考虑下面的代码:使用原始类型列表作为参数 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 ... 由于跳过了泛型类型检测所以使用原始类型的集合是危险,不安全的。Set, Set<?> 和Set<Object>之间是有很大的区别的。 |