美文网首页Java基础面试技巧
List集合常见错误总结(经验教训)

List集合常见错误总结(经验教训)

作者: 莫问以 | 来源:发表于2019-04-15 18:23 被阅读29次

    新手都容易犯这个错误,先看代码:

            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修饰,但是效率比较低,如果要考虑线程安全的话可以用。

    相关文章

      网友评论

        本文标题:List集合常见错误总结(经验教训)

        本文链接:https://www.haomeiwen.com/subject/vtrpwqtx.html