新手都容易犯这个错误,先看代码:
List<String> list = new ArrayList<String>();
for(int i=0;i<list.size();i++){
System.err.println(list.get(i).toString());
}
if(list!=null){
System.out.println("不为空");
}else{
System.out.println("为空,需进行赋值判断");
}
结果是不为空.png
改代码如下:
if(!list.isEmpty()){
System.out.println("不为空");
}else{
System.out.println("为空,需进行赋值判断");
}
改成以上代码,ok了!这个错误就是对集合判断是否为Null出错,需要加上list.size()>0或者使用才可以list.isEmpty()才行。
List list=new ArrayList();
像这样的list不为null(我们会错误地以为此时list为null),但是判断size的时候,实则是为0,所以判断集合的时候,一定记得要双重判断。即list!=null && list.size()>0才好。
PS:list.isEmpty()和list.size()==0 没有区别, isEmpty()判断有没有元素,而size()返回有几个元素,如果判断一个集合有无元素,建议用isEmpty()方法,该方法简单、清晰明了!
public class ListGu {
private static List<String> list;
public static void main(String[] args) {
setList();
}
//对集合重新赋值
private static void setList() {
for(int i=0;i<10;i++){
list.add(String.valueOf(i));
}
for(int i=0;i<list.size();i++){
System.err.println(list.get(i).toString());
}
}
}
上面的代码乍一看,没毛病,可是一运行:
竟然报空指针异常.png按住ctrl键,点List进去看底层源码:
List底层源码.png擦,竟然是个接口,竟然没new对象就直接赋值。发现问题,及时改正:
public class ListGu {
private static List<String> list;
public static void main(String[] args) {
setList();
}
//对集合重新赋值
private static void setList() {
for(int i=0;i<10;i++){
list = new ArrayList<String>(); //new对象
list.add(String.valueOf(i));
}
for(int i=0;i<list.size();i++){
System.err.println(list.get(i).toString());
}
}
}
运行代码,竟然不是预想中的结果:
竟然不是预想中的结果.png这又是为什么呢?现在我们知道,使用List时,需要new对象,仔细一看,擦,竟然在循环里new对象,这种错误,特别容易犯!!
public static void main(String[] args) {
List<List<String>> list=new ArrayList<>();
List<String> list2=new ArrayList<>();
for(int i=0;i<10;i++){
list2.add(""+i);
list.add(list2);
list2.clear();
}
// 遍历List
for(int i=0;i<list.size();i++){
System.err.println(list.get(i).toString());
}
}
乍一看以上代码,没毛病,很简单的逻辑,少new一个对象,可以达到节省优化代码,节省虚拟机内存,可是一运行,擦,竟然是这样的结果:
结果竟然是null.png这个错误引起就是因为list中存储的是对象的引用,而不是对象本身。如果不清楚这一点,会常踩这个坑。该代码虽然可以达到一个对象重复使用的效果,但是因为list存储的是对象的引用,所以当list2.clear()的时候,list中的list2也会clear,这样最后得到的就只能是一堆空的集合。
集合对照图.png上图完美的诠释了集合之间的关系,常见的集合分三大类:List,Set和map三种,List与Set是继承自Collection,而map(这里指统称)继承自Map。
List与Set的区别
List中的元素有存放顺序,而且可存放重复元素,检索效率高,插入删除效率低
Set没有存放顺序,而且不可以存放重复元素,后来的元素会把前面重复的元素替换掉,检索效率低,插入删除效率高。
(Set存储位置由HashCode码决定,所以它存储的对象必须有equals()方法,而且Set遍历只能用迭代,因为它没有下标。)
Vector和ArrayList与LinkedList
LinkedList与ArrayList是互相弥补对方而存在,二者为互补关系,所以如果使用过程中觉得ArrayList的缺点太多,你就可以使用LinkedList,相反也是如此。
ArrayList的特点?
集合中元素存储的位置是连续的,所以查询起来会比较快,但是插入删除效率低(会引起其他元素位置的变化)。
LinkedList的特点?
集合中元素位置是任意的,所以执行插入删除操作效率较高,查询效率较低。
Vector的特点?
线程安全,因为很多方法都用synchonized修饰,但是效率比较低,如果要考虑线程安全的话可以用。
网友评论