zoukankan      html  css  js  c++  java
  • 集合、Collection、迭代器、List

    数组存对象

    package CollectionTest;
    
    public class Student {
        //变量私有,给出get方法提供变量
        //某些属性成员变量不要让外界任意访问
        private String name;
        private int age;
        public Student(){}
        public Student(String name, int age){
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
      //也可以重写toString()方法
       public String toString() {
           return "Student [name=" + name + ", age=" + age + "]";
        } }
    public class ArrayDemo1 {
    
        public static void main(String[] args) {
            Student[] s = new Student[5];
            Student s1 = new Student("zed1",1);
            Student s2 = new Student("zed2",2);
            Student s3 = new Student("zed3",3);
            Student s4 = new Student("zed4",4);
            Student s5 = new Student("zed5",5);
    
            s[0] = s1;
            s[1] = s2;
            s[2] = s3;
            s[3] = s4;
            s[4] = s5;
            
            //下面代码输出哈希码,数组存储的是对象
            //for(int i = 0; i < s.length; i++){
            //    System.out.println(s[i]);
            //}
            
            for(int i = 0; i < s.length; i++){
                Student ss = s[i];
                System.out.println(ss.getName() + "---" + ss.getAge());
            }
        }
    
    }

       数组长度是固定的,所以有时候需要用到集合。

      为什么出现集合类?
          面向对象语言对事物体现都是以对象的形式,所以为了方便对多个对象的操作,java就提供了集合类。
      数组和集合类同是容器,有何不同?
          数组虽然也可以存储对象,但长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
      集合类特点
          集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

    数组没有length方法,只有length属性。
    字符串有length方法。
    集合有size方法。

        ECLIPSE复制粘贴代码很容易把包一下导过来了,所以要注意。

    public class Student {
        //变量私有,给出get方法提供变量
        //某些属性成员变量不要让外界任意访问
        private String name;
        private int age;
        public Student(){}
        public Student(String name, int age){
            this.name = name;
            this.age = age;
        } 
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
       //如果要重写toString()方法,放掉注释
    /* public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }*/ }

      添加对象到集合的三种方式:

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionTest2 {
    
        public static void main(String[] args) {
    
            Collection<Student> c = new ArrayList<>();
            
            // 三种往集合中添加对象的方法
            // 方法一
            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            c.add(s1);
            c.add(s2);
            
            //方法二
            c.add(new Student("zed3", 3));
            c.add(new Student("zed4", 4));
            
            //方法三 使用类中setter方法
            Student s5 = new Student();
            Student s6 = new Student();
            s5.setName("zed5");
            s5.setAge(5);
            s6.setName("zed6");
            s6.setAge(6);
            
            //如果对象所在类重写了toString()方法,可以直接输出,如果没有重写,输出的是哈希码
            System.out.println(c);
            
            System.out.println("-----------------------------");
            
            Iterator it = c.iterator();
            while(it.hasNext()){
                //强制转换成Student类型
                Student s = (Student)it.next();
                System.out.println(s.getName() + "-----" + s.getAge());
            }
        }
    
    }

      clear()清空元素

            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
    
            c1.add(s1);
            c1.add(s2);
            c1.add(s3);
            
            Iterator it = c1.iterator();
            while(it.hasNext()){
                //强制转换成Student类型
                Student s = (Student)it.next();
                System.out.println("c1" + s.getName() + "--未清空元素---" + s.getAge());
            }
            //移除所有元素
            c1.clear();
            System.out.println("c1" + "--清空元素---"+ c1);

      是否包含某元素contains:

            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
    
            c1.add(s1);
            c1.add(s2);
            c1.add(s3);
            
            Student s8 = new Student("zed8", 8);
            System.out.println("是否包含某元素: "  + c1.contains(s8));//false
            System.out.println("是否包含某元素: "  + c1.contains(s1));//true

       判断集合是否为空:

            //判断集合是否包含元素,空集合返回true
            System.out.println("集合中是否包含元素(未使用clear()方法): " + c1.isEmpty());
            c1.clear();
            System.out.println("集合中是否包含元素(已使用clear()方法): " + c1.isEmpty());

      删除指定对象:  

            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
    
            c1.add(s1);
            c1.add(s2);
            c1.add(s3);
            //删除指定元素
            //未清空元素 [Student [name=zed1, age=1], Student [name=zed2, age=2], Student [name=zed3, age=3]]
            System.out.println("未清空元素 " + c1);
            c1.remove(s2);
            //清空元素s2之后 [Student [name=zed1, age=1], Student [name=zed3, age=3]]
            System.out.println("清空元素s2之后 " + c1);

      集合大小size()方法和转换成数组toArray()方法:

            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
    
            c1.add(s1);
            c1.add(s2);
            c1.add(s3);
            //集合元素数量
            System.out.println(c1.size());
            
            //转换成数组
            //强制转换成Student类型
            //Student[] s = (Student)c1.toArray(); 这个转换是错误的
            Object[] s =c1.toArray();
            for(int i = 0; i < s.length; i++){
                System.out.println(s[i]);
            }

       求交集、并集等:

            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
    
            c1.add(s1);
            c1.add(s2);
            c1.add(s3);
            
            Student s4 = new Student("zed4", 4);
            Student s5 = new Student("zed5", 5);
            Student s6 = new Student("zed6", 6);
            c2.add(s4);
            c2.add(s5);
            c2.add(s6);
            
            //将一个集合添加到另一个集合中,添加成功返回true
            System.out.println("是否添加成功 " + c1.addAll(c2));
            for(Student c : c1){
                System.out.println(c);
            }
            
            //判断集合中是否包含另一集合所有元素
            System.out.println("是否包含另一个集合所有元素 " + c1.containsAll(c2));
            
            //仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作),求交集
            //删除掉另一集合不包含的元素,如果删除成功返回true。
            System.out.println("求交集 " + c1.retainAll(c2));
            System.out.println("求交集删除成功,输出交集 " + c1);
            
            //删除c1集合和c2集合的交集
            c1.removeAll(c2);
            System.out.println("删除交集元素之后输出 " + c1);

    迭代器

      迭代器是遍历集合的一种方式
      迭代器是依赖于集合而存在的
      迭代器为什么不定义成一个类,而是一个接口?
       Java提供很多集合类,这些集合类的数据结构是不同的,存储方式和遍历的方式应该是不同,进而它们的遍历方式也应该不一样。
       在真正的具体实现在子类的内部类中

      迭代的三种方法:

      迭代的时候要注意强制转换数据类型。

            Collection<Student> c = new ArrayList<>();
            
            Student s1 = new Student("zed1", 1);
            Student s2 = new Student("zed2", 2);
            Student s3 = new Student("zed3", 3);
            
            c.add(s1);
            c.add(s2);
            c.add(s3);
            
            //方法一
            Iterator<Student> it = c.iterator();    
            while(it.hasNext()){
                //强制数据类型转换
                Student s = (Student)it.next();
                System.out.println(s);
            }
            
            //方法二
            //这种方法效率最高,for循环完迭代器就编程垃圾了
            //for(初始化语句; 条件语句; 此处可以为空)
            for(Iterator<Student> it = c.iterator(); it.hasNext(); ){
                System.out.println(it.next());
            }
            
            //方法三
            for(Object obj : c){
                //for each两种方式都可以,如果是调用对象方法的话,要强制进行类型转换
                //System.out.println(obj);
                System.out.println(((Student) obj).getName() + "----" + ((Student) obj).getAge());
            }

      迭代器中使用remove()方法,删除的是集合中的元素,而不只是迭代器中的。

            Iterator<Student> it = c.iterator();    
            while(it.hasNext()){
                System.out.println(it.next());
                it.remove();
                
            }
            System.out.println("迭代器使用remove方法之后,集合中元素的个数为: " +c.size());

      上面程序如果先调用remove()方法,再调用next()方法,会抛出IllegalStateException错误。

            Iterator<Student> it = c.iterator();    
            while(it.hasNext()){
                //下面是将it.next()强制转换成Student类型
                System.out.println(((Student)it.next()).getName() + "------" + ((Student)it.next()).getAge());
                //请注意,上面命令,((Student)it.next()).getName()和((Student)it.next()).getAge()得到的变量不属于同一个对象
                //因为getAge()已经是第二次调用next()方法了
            }

    List

      List接口概述
          有序的Collection(也成为序列)。此接口用户可以对列表中的每个元素的插入位置进行精确控制。用户可以根据元素的整数索引访问元素,并搜索列表中的元素。
          与set不同,列表通常允许重复的元素
      List案例
          存储字符串并遍历
          存储自定义对象并遍历
      List集合特点
          有序(存储和取出的元素一致),可重复的。

            List<String> l = new ArrayList<>();
            
            //可重复,放入取出顺序一致
            l.add("java");
            l.add("jse");
            l.add("jee");
            l.add("jee");
            
            Iterator it = l.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }

      List相比Collection增加的几种方法:

            List<String> l = new ArrayList<>();
            l.add("1---java");
            l.add("2---jse");
            l.add("3---jee");
            l.add("3---jee");
            
            //在指定位置添加元素
            l.add(0, "hello");
            Iterator it = l.iterator();
            while(it.hasNext()){
                System.out.println(it.next());
            }
            System.out.println("------------------------");
            
            //获取指定位置的元素
            System.out.println("获取指定位置的元素  " + l.get(2));
            
            //返回第一次出现位置的索引
            System.out.println("第一次出现指定元素的索引 " + l.indexOf("3---jee"));
            //如果不包含该元素返回-1
            System.out.println("第一次出现指定元素的索引,不包含jee,返回-1   : " + l.indexOf("jee"));
            
            //返回列表中最后出现指定元素的索引
            System.out.println("最后一次出现指定元素的索引 " + l.lastIndexOf("3---jee"));
            
            //移除列表中指定位置的元素,并返回该元素
            System.out.println("移除指定位置的元素并返回 " + l.remove(4));
            System.out.println(l);
            
            //用指定元素替换列表中指定元素,并返回
            System.out.println("替换元素" + l.set(3, "JavaEE"));
            System.out.println(l);
            
            //List<E> subList(int fromIndex, int toIndex) 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图
            List l2 = l.subList(1, 3);
            System.out.println(l2);

      List特有遍历功能:

    /*
        List特有遍历功能:
            size()和get()方法结合
        */
    for(int i = 0; i < list.size(); i++){
        String s = (String)list.get(i);
        System.out.println(s);
        }

      ListIterator一般不使用

            List<String> l = new ArrayList<>();
            l.add("1---java");
            l.add("2---jse");
            l.add("3---jee");
            //listIterator继承了Iterator,所以可以用hasNext()和Next()
            //这样没有任何意义,要实现逆向遍历必须先正向遍历,因为指针在正向开始处
            ListIterator lit = l.listIterator();
            while(lit.hasPrevious()){
                String s = (String)lit.previous();
                System.out.println(s);
            }
        }
    迭代器是依赖于集合存在的,在判断成功后,集合中新添加了元素.
    而迭代器却不知道,所以就报错了。这个错叫并发修改异常
    其实这个问题描述的是迭代器遍历元素的时候,通过集合是不能修改元素的。
                List<String> l = new ArrayList<>();
                l.add("1---java");
                l.add("2---jse");
                l.add("3---jee");
                Iterator it = l.iterator();
                while(it.hasNext()){
                    String s = (String)it.next();
                    //此处会发生并发修改异常
                    if("world".equals(s)){
                        list.add("javaee");
                        }
                    }
    如何解决呢?
        A、迭代器遍历的时候,用迭代器修改元素;
                元素是跟在刚才迭代元素的后面的
                        List<String> l = new ArrayList<>();
                        l.add("1---java");
                        l.add("2---jse");
                        l.add("3---jee");
                        ListIterator it = l.listLterator();
                        while(it.hasNext()){
                            String s = (String)it.next();
                            if("world".equals(s)){
                                it.add("javaee");
                                }
                            }
        B、集合遍历元素,集合修改元素(普通for)

     

     List:
        ArrayList:底层是数组 增删慢 查询快 线程不安全 效率高
        Vector:底层是数组 增删慢 查询快 线程安全 效率低
        LinkedList:底层是链表 增删快 查询慢 线程不安全 效率高

     

  • 相关阅读:
    github误fork后删除
    初识javascript
    struts验证框架失效
    Java基础学习1Java标识符及基本类型
    dos 命令行方式下启动和停止MySql服务
    html
    给文本框添加边框的两种方法
    银行家算法
    解决MyEclipse里Tomcat端口被占用而无法启动的情况
    Java近似圆
  • 原文地址:https://www.cnblogs.com/changzuidaerguai/p/6839112.html
Copyright © 2011-2022 走看看