1.Array 转换成ArrayList
为了将Array转换成ArrayList,程序员会经常这样做:
List<String> list = Arrays.asList(arr);
Arrays.asList() 会返回ArrayList,但是这个类是Array包下的私有静态类,这个类不是java.util.ArrayList。而java.util.Arrays.ArrayList这个类有 set(), get(), contains() 方法,但是没有一个方法可以去为列表添加元素,所以调用这个方法返回的列表的size是固定的,为了创建一个真正的ArrayList,你应该这样做:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
经过这样处理后的ArrayList,其构造方法参数是可以接受集合类型的。
2.判断Array是否包含某个值
一般会这样做
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
这样的代码是可以运行的,并可以达到想要的效果的,但是没必要将一个list转换成set, 转换成set往往需要更多的时间,可以这样优化:
Arrays.asList(arr).contains(targetValue);
或者可以这样
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
第一种方式的可读性比第二种要高
3.循环list,删除某个元素
想想下面这段代码的输出结果
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的size变小,list的索引变了,所以当你在一个遍历list的循环中去删除多个元素时,运行的结果就是你想要的。
你可能知道使用迭代器是是删除某元素的一种正确的方式,而且你也知道for循环遍历迭代器遍历原理是一样的,但事实上是不一样的,想想下面这段代码的结果:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (String s : list) {
if (s.equals("a"))
list.remove(s);
}
它将会抛出 ConcurrentModificationException. 异常。但是如果修改代码成这样,是OK的
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()之前调用,在上面那段代码中的for循环中,编译器将会在元素被移除之后才会去调用 .next() ,这样就会抛出ConcurrentModificationException. 可以去看看ArrayList.iterator().的源码。
4.Hashtable vs HashMap
在计算机的算法的约定下,Hashtable 是数据结构的名字,但是在Java中,数据结构的名字是HashMap, 这两者最关键的不同是否是异步,Hashtable是异步的。所以一般情况下,不会用Hashtable,而是HashMap。
#5.用好集合中的原始类型
在Java中,原生类型和未绑定泛型很容易混合起来使用,拿Set举例,Set是原生类型,然而Set<?>是一个未绑定的泛型。
仔细看看下面的代码,其中的List参数是一个原始的类型
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 …
使用原生类型集合是非常危险的,因为原始类型会跳过泛型的检查