1.将数组转换为ArrayList
为了将数组转换为ArrayList,开发者经常会这样做:
List<String> list = Arrays.asList(arr);
Arrays.asList()会返回一个ArrayList,但这个ArrayList是Arrays的私有静态类,不是java.util.ArrayList。java.util.Arrays.ArrayList有set(), get(), contains()方法,但没有任何能增加元素的方法,所以它的大小是确定的。
为了创建一个真正的ArrayList,应该这样做:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
ArrayList的构造函数能够接收一个Collection类型,而它也是java.util.Arrays.ArrayList的一个祖先类。
2.检查一个数组是否包含某个值
开发者经常这样做:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
这个的代码可以工作,但没必要首先把数组转换为集合,把数组转换为集合需要额外的时间。可以这样做:
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]
上面的方法有一个严重的问题。当一个元素被移除后,列表的大小减小了,索引也就变了。所以希望利用索引在一个循环里边删除多个元素是做不到的。
你可能知道利用迭代器在一个循环里边删除元素是正确的方法,并且知道Java的foreach循环很像一个迭代器,但事实上不是。思考下面的代码:
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循环里边,编译器会先调用.remove(),再调用.next(),从而导致异常ConcurrentModificationException。你可能想知道ArrayList.iterator()的源代码。