美文网首页java基础入门
Java基础——集合

Java基础——集合

作者: 阿Q说代码 | 来源:发表于2019-02-20 14:13 被阅读67次

    首先呢,给大家讲一下集合的由来:java的思想是面向对象思想,如果想统一的管理所有的对象,就涉及到用容器来储存对象,而对象数组是可以存储对象的,但是数组有一个缺点就是长度固定,为了突破这一限制 ,集合就应运而生了。

    数组和集合的优缺点

    长度:数组固定,集合可变;
    内容:集合只能存储引用类型,数组可以存储基本类型和引用类型。

    集合体系

    单列集合顶层接口
    Collection
        |-List有序(存入和取出顺序相同) 存入的元素可以重复 有索引 可以通过索引来操作元素
            |-ArrayList 数组结构
            |-LinkedList    链表结构
            |-Vector    数组结构
        |-Set 无序(存入和取出顺序不同) 存入的元素不可以重复
            |-HashSet    哈希算法
            |-TreeSet   二叉树算法
    双列集合
    Map
        |-HashMap
        |-TreeMap
    
    Collection

    常用方法

    boolean add(E e):向集合中添加元素e,添加成功返回true,添加失败返回false(List集合永远添加成功 Set集合就有可能添加失败因为Set集合会去掉重复元素)
    boolean remove(Object o):删除集合中的元素o,删除成功则true,删除失败则false
    void clear():清空集合里面的元素
    boolean contains(Object o):集合是否包含元素o,如果包含返回true,如果不包含返回false
    boolean isEmpty():判断集合是否为空
    int size():集合的长度
    集合的长度:c.size();
    字符串长度:s.length();
    数组的长度:arr.length;

    代码演示:

    public static void main(String[] args) {
        Collection c = new ArrayList();     //父类引用指向子类对象
        boolean b1 = c.add("abc");          //添加一个字符串
        boolean b2 = c.add(true);           //自动装箱new Boolean(true);
        boolean b3 = c.add(100);            //自动装箱new Integer(100);
        boolean b4 = c.add(new Student("张三",23));   //添加一个自定义对象 
        boolean b5 = c.add("abc");          //添加一个重复的字符串
    
        System.out.println(b1);     //true
        System.out.println(b2);     //true
        System.out.println(b3);     //true
        System.out.println(b4);     //true
        System.out.println(b5);     //true
    
        System.out.println(c);//[abc, true, 100, Student [name=张三, age=23], abc]  
        //ArrayList的父类重写了Object的toString()
    
        Collection c1 = new ArrayList();        //父类引用指向子类对象        
        c1.add("a");
        c1.add("b");
        c1.add("c");
        c1.add("d");
    
        c1.remove("b");                 //删除指定元素
        System.out.println(c1);             //[a, c, d]
    
        System.out.println(c1.contains("b"));       //false  判断是否包含
        System.out.println(c1.contains("c"));       //true  判断是否包含
    
        System.out.println(c1.size());          //3  长度为3 
    
        System.out.println(c1.isEmpty());       //false  不为空
    
        c1.clear();                 //清空集合                                      //清空集合
        System.out.println(c1);             //[]
    }
    

    Object[] toArray():集合转数组 (可以用来遍历)

    代码演示:

    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add(new Student("张三", 23));       //自动类型提升:Object obj = new Student("张三",23);
        c.add(new Student("李四", 24));
        c.add(new Student("王五", 25));
        c.add(new Student("赵六", 26));
    
        Object[] arr = c.toArray();     //将集合转换成数组
        for (int i = 0; i < arr.length; i++) {
            Student s = (Student)arr[i];    //向下转型
            System.out.println(s.getName() + "..." + s.getAge());
        }
    }
    

    不常用的带All的方法

    boolean addAll(Collection c):添加 c里面的所有元素
    boolean removeAll(Collection c):删除交集
    boolean containsAll(Collection c):是否全部包含
    boolean retainAll(Collection<?> c):取交集

    迭代器 Iterator

    迭代器的原理

    Iterator是个接口,是通过集合里面的内部类实现的。迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法。这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部定义自己迭代方式,这样做的好处有二:第一、规定了整个集合体系的遍历方式都是hasNext()和next()方法;第二、代码有底层内部实现,使用者不用管怎么实现的,会用即可。

    代码演示:

    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add(new Student("张三", 23));       //Object obj = new Student("张三",23);
        c.add(new Student("李四", 24));
        c.add(new Student("王五", 25));
        c.add(new Student("赵六", 26));
            
        //获取迭代器
        Iterator it = c.iterator();
        while(it.hasNext()) {
            System.out.println(((Student)it.next()).getName()+"  "+
                        ((Student)it.next()).getAge());//如果这样写的话  打印结果为  zhangsan  14 并且报错java.util.NoSuchElementException 因为next()方法调用一次,指针就往后走一次
            
            Student s = (Student)it.next(); //所以一般while循环里面 就出现一次next(),如果想使用多次 请用一个变量接受next()方法的返回值 
            System.out.println(s.getName()+"  "+s.getAge());
        }
    }
    
    List接口

    List的特有方法

    void add(int index,E element);在指定的index位置插入element元素
    E remove(int index);删除index位置上的元素
    E get(int index);获取指定index位置上的元素。可以用来遍历List集合,而且这种遍历方式是List特有的遍历方式
    E set(int index,E element);把集合中index位置上的元素用element元素替换

    concurrentModificationException:并发修改异常

    原因:在用迭代器遍历集合的时候,我们通过集合改变了元素,而迭代器是通过集合得到的,集合发生了改变,而迭代器还是通过原来的集合得到的,所以产生了并发修改异常。
    解决:

    1. 通过迭代器遍历集合的时候,我们通过迭代器来改变集合元素,而这时候原来Iterator没有添加元素的方法,所以就用ListIterator,因为ListIterator里面有add方法
    2. 通过普通for循环来遍历集合的时候,用集合来改变元素

    代码演示:

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("a");              //Object obj = new String();
        list.add("b");
        list.add("world");
        list.add("c");
        list.add("d");
        list.add("e");
    
        //报并发修改异常原因:
        Iterator it = list.iterator();  //获取迭代器
        while(it.hasNext()) {           //判断集合中是否有元素
            String str = (String)it.next(); //向下转型
            if("world".equals(str)) {
                //遍历的同时在用集合调用add方法增加元素,并发修改ConcurrentModificationException
                list.add("javaee"); 
            }
        }
    
        //解决方案一
        ListIterator lit = list.listIterator();//获取迭代器(List集合特有的)可以通过hasPrevious()和previous()来往前遍历
        while(lit.hasNext()) {
            String str = (String)lit.next();//向下转型
            if("world".equals(str)) {
                lit.add("javaee");  //遍历的同时用迭代器调用add方法添加元素就没问题
            }
        }
    
        //解决方案二
        for (int i = 0; i < list.size(); i++) { //通过普通for循环来遍历集合的时候,用集合来改变元素
            String str = (String)list.get(i);
            if("world".equals(str)){
                list.add("javaee");
            }
        }
    
        System.out.println(list);
    }
    

    ArrayList

    基本上都是从List实现的方法,因此没有特有的方法。
    案例:ArrayList去除集合中字符串的重复值(字符串的内容相同)

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("b");
        list.add("c");
        list.add("c");
        list.add("c");
        list.add("c");
            
        ArrayList newList = getSingle(list);
        System.out.println(newList);
    }
    /*
    * 分析:
    * 1,创建新集合
    * 2,根据传入的集合(老集合)获取迭代器
    * 3,遍历老集合
    * 4,通过新集合判断是否包含老集合中的元素,如果包含就不添加,如果不包含就添加
    */
    public static ArrayList getSingle(ArrayList list) {
        ArrayList newList = new ArrayList<>();      //1,创建新集合
        Iterator it = list.iterator();          //2,根据传入的集合(老集合)获取迭代器
    
        while(it.hasNext()) {               //3,遍历老集合
            Object obj = it.next();         //记录住每一个元素
            if(!newList.contains(obj)) {    //如果新集合中不包含老集合中的元素
                newList.add(obj);           //将该元素添加
            }
        }
        return newList;
    }
    

    LinkedList

    public void addFirst(E e)将指定元素插入此列表的开头。
    public void addLast(E e)将指定元素添加到此列表的结尾。
    public E removeFirst()移除并返回此列表的第一个元素。
    public E removeLast()移除并返回此列表的最后一个元素。
    public E getFirst()返回此列表的第一个元素。
    public E getLast()返回此列表的最后一个元素。

    代码演示:

    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.addFirst("a");
        list.addFirst("b");
        list.addFirst("c");
        list.addFirst("d");
        list.addLast("e");
        System.out.println(list.getFirst());    //d
        System.out.println(list.getLast()); //e
        System.out.println(list.removeFirst()); //d
        System.out.println(list.removeLast());  //e
        System.out.println(list);       //[c, b, a]
    }
    

    栈和队列:
    栈: 先进后出
    队列: 先进先出

    Vector

    jdk1.0出现1.2并入到List体系,后来被ArrayList替代,所以了解即可。

    附:
    数组结构:查询快 增删慢
    链表结构:查询慢 增删快

    List的三个儿子的特点
    ArrayList:查询快 增删慢 不安全 效率高
    LinkedList:查询慢 增删快 不安全 效率高
    Vector:查询快 增删慢 安全 效率低

    好了集合部分就先说到这了,想了解更多学习知识,请关注微信公众号“阿Q说”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

    相关文章

      网友评论

        本文标题:Java基础——集合

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