zoukankan      html  css  js  c++  java
  • collection 集合

    Collection接口常用的子接口有:List接口、Set接口

    List接口常用的子类有:ArrayList类、LinkedList类

    Set接口常用的子类有:HashSet类、LinkedHashSet类

    常用集合类的继承结构如下:
    Collection(接口)<–List(接口)<–Vector
    Collection(接口)<–List(接口)<–ArrayList
    Collection(接口)<–List(接口)<–LinkedList
    Collection(接口)<–Set(接口)<–HashSet(实现类)
    Collection(接口)<–Set(接口)<–HashSet(实现类) <–LinkedHashSet (实现类)
    Collection(接口)<–Set(接口)<–SortedSet(接口)<–TreeSet(实现类)
    Map(接口)<–SortedMap(接口)<–TreeMap(实现类)
    Map(接口)<–HashMap(实现类)

    Collection
    |–List
    有序(存储顺序和取出顺序一致),可重复
    |–Set
    无序(存储顺序和取出顺序不一致,但它有自己的存储顺序),唯一

    牢记:
    ArrayXxx:底层数据结构是数组,查询快,增删慢
    LinkedXxx:底层数据结构是链表,查询慢,增删快
    HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
    TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

    原文链接:https://blog.csdn.net/qq_31360933/article/details/79337483

     Collection是接口不能new对象所以的多态借用子类对象:

    格式:创建集合的格式:

    方式1:Collection<元素类型> 变量名 = new ArrayList<元素类型>();

    方式2:Collection 变量名 = new ArrayList();


    ArrayList继承了AbstractList同时又实现接口List,而List接口又继承了Collection接口,Collection是集合中最顶层的接口了;Collection是所以集合的祖宗
    List接口:怎么存就怎么取,有数组下标,可以存重复元素:  

    常有的类:ArrayList类;  LinkedList类;
    Set接口:怎么存的不一定怎么取,没有数组下标,不可以存重复数据   ;

     

    //往集合中添加对象元素。add(E e)方法,E代表创建集合时所指定的数据类型如<String>,那么,E就代表String类型;创建集合时若没有指定数据类型,那么,E就代表Object类型。
    
    ArrayList<Person> list =new ArrayList<Person> ();
           list.add(new Person("胡德正",12));
           list.add(new Person("姜发财",25));
           //遍历
           for(int i=0;i<list.size();i++) {
            System.out.println(list.get(i));        
           }
    
    /*这里直接添加了Person对象,因为重写构造方法所以直接赋值
    System.out.println(list.get(i)) 如果Person类中没有重写toString方法那么这里打印的是地址;但是Person重写了tostring方法那么这里打印的方法内的内容*/
    Collection<Integer> col=new ArrayList<Integer>();
    因为Collection是接口不能new对象所以这里借用了子类ArrayList创建对象,是多态

    Collection的基本操作:

    1.添加元素:col.add(123);

    2.删除元素:col.remove(123);这里删除直接写集合内要删除的内容不需要写下标
    3.清空集合:col.clear;把集合中的内容删了,但是集合还在


    .因为Collection是接口不能new对象所以的向下转型才能遍历集合:

       Collection<Integer> col =new ArrayList<Integer>();
         col.add(123);
        col.add(456);
        col.add(789);
    
         //删除元素
           col.remove(456);
           //清空集合
          col.clear
    //是多态需要向下转型遍历
    
         if(col instanceof ArrayList)  ArrayList<Integer> list=(ArrayList<Integer>)col;
    
         for(int i=0;i<list.size();i++) {
    
            System.out.println(list.get(i));
         }
    //判断集合中是否包含某个元素
         boolean flag=col.contains(999);
         System.out.println(flag);
         //将集合转为数组  转型
         Object[] arr=col.toArray();
         for(int i=0;i<arr.length;i++) {
            System.out.println(arr[i]);    
         }
    集合转为数组:Object arr=col.toArray();因为Collection的.toArray()方法返回值是Object所有用Object arr接
    再进行遍历值:for(inti=0;i<arr.length;i++){system.out.println(arr[i])};

     

    Iterator迭代器


    Collection获取集合内的元素是通过迭代器实现的:

    定义:迭代器对象Iterator会先对Collection进行判断用.hasnext()方法进行判断如果有就返回true没有就返回false;

    如果.hasNext()返回的是true那么再调用.next()方法把Collection中的值取出来,迭代器取值是判断一次去一次值;然后再判断再取值
    
    Collection<String> col = new ArrayList<String>();
         col.add("将发财");
         col.add("胡德正");
         col.add("吾皇");
    
         //首先 获取迭代器对象
         Iterator<String> it = col.iterator();
    
    //遍历和上面一样、
    
    //判断
         while(it.hasNext()){
    
           //如果为true 则取元素
           String str=it.next();
    
    //进行比较
           if(str.equals("哪吒")) {
           System.out.println(str);}    
    
         }
    
    /*取值需要先获取迭代器对象:
    Iterator<String> it=col.iterator();
    调用Collection的对象col调取iteartor()方法获取迭代器对象;
    
    再赋值给it;
    迭代器Iterator的泛型要和 Collection要被遍历的集合一样;
    
    it.hasNext()是判断集合中是否还有值有就返回true再调用it.next()方法取值,没有就返回false然后结束
    
    在利用迭代器循环取值:*/
    while(it.haxnext()){system.out.println(it.next())};
    
    while循环里面条件只有true和false那么默认就true所以it.haxnext()就是it.haxnext()==true
    利用判读字符内容来取值:
    
    while(it.hasnext()){String str="哪吒"
    
    ;if(str.equals("哪吒")){
    
    system.out.println(str)
    
    }
    
    /*判断字符是哪吒后再输出;一定先定义和变量;再判断输 出变量;
    
    因为collection是先判断有没有值然后再取值的所以的先定义个变量str接收了才能保存住要不然输出的是下一个值*-/

    泛型
    集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。

    Collection col=new ArrayList();//如果不加泛型,就可以什么都向集合存,不加泛型自动转成Object类型
    col.add(123);//不加泛型系统自动把值提升为object类型
    col.add("123");
    col.add(123.456);
    //获取迭代器对象
    Iterator it=col.iterator();//因为上面的集合没写泛型所以这里迭代器对象也不写泛型
    while(it.hasNext()){
    Object obj=it.next();//因为集合里没写泛型值都生成Object;所以这里也用Object来接
    if(obj instanceof String){
    String s=(String)obj;//转成字符串
    System.out.println(s.length());
    }
    }



    增强for

    public static void main(String[] args) {
    
        //容器
        Collection<String> col=new ArrayList<String>();//定义为String 类型
    
        //存值
        col.add("a");
        col.add("b");
        col.add("c");
    
        //自定义类型用for方便
        //增强for循环,不通过下标,底层有迭代器,增强for迭代器中不能改变集合长度(曾 删操作);普通for可以改变
    
        for(String s:col ) {
    
            System.out.println(s);
    
        }
    
    }

    增强for:

       专门用来变量数组和集合的(没有下标)不能打印有下标的集合数组(打印1-100的值);

      它的内部原理是迭代器Interator,所以在打印过程中不能对集合中的元素
    进行增删,但可以修改;只要不改变集合/数组的长度都行.
    格式:个人理解

    for(要遍历的元素类型(String)  变量名(p): Collection集合or数组(arr))

    {system.out.println(p)};

    格式:

    for(元素的数据类型 变量 : Collection集合or数组){

    }


    增强for和老式的for循环的区别:

    增强for的循环必须要有目标,且目标只能是Collection的数组和集合,在遍历时如果只是对数组和集合进行遍历那么就用增强for
    如果还需要对数组和集合的元素进行操作那么就用老式for循环,通过对下标的操作进行增删改;

     

    public static void main(String[] args) {
    
      Collection<Person> col=new ArrayList<Person>();
       col.add(new Person("傲丙",18));
       col.add(new Person("金吒",28));
       col.add(new Person("木栅",15));
       for(Person ss:col) {内置原理是迭代器Interator,先判断col集合里面是否有值(has.next())再进行取值(.next())然后把取到的值赋给s;
    再打印是;然后再判断,再取值,再复制,打印
    System.out.println(ss); 这里是增强for打印自定义的Person类,把col的值赋值到Person类型的p对象里面,然后再打印p,
    因为Person重写了toString()方法所以这里打印的toString()方法里面的内容而不是地址 } 增强for和迭代器不能增删但是可以修改,只有不改变集和的长度就行,如果想增删改就用老式for,因为增强for和迭代器一样一直往下走不能回头,就不能改变长度

     泛型的定义与使用

    用一个方法遍历多种Collection集合,(通配符<?>;当做泛型)

    public static void main(String[] args) {
    
      //重写toStrion调用本类方法,不重写就调用Object中的方法
    
      Collection<Person> col=new ArrayList<Person>();
      col.add(new Person("善思",12));
      col.add(new Person("章鱼",45));
    
      Collection <Student> col2= new ArrayList<Student>();
      col2.add(new Student("夏","女"));
      col2.add(new Student("商","男"));
    
      //调用同一方法,遍历集合
    
      get(col);
      get(col2);
    
    }
    
      //泛型通佩符号?
    public static void get( Collection<?> col) {   // (Collection<?> col)中的?是通配符,在不知道泛型是什么的时候就有?代替泛型这样就能调用多种collection泛型的集合
      //获取迭代器,因为重写了 tostring古it打印字符
      Iterator<?> it=col.iterator();
    
    曾强for不能遍历带有通配符?的集合,因为增强for不认识通配符?;只能用迭代器进行遍历
    
      while(it.hasNext()) {
         System.out.println(it.next()) 
      }
    }

     

     

     

     

    泛型限定

     

    public static void main(String[] args) {
    
         Collection<cook> coll = new ArrayList<cook>();
    
         coll.add(new cook());
    
         Collection<waiter> col2 = new ArrayList<waiter>();
    
         col2.add(new waiter());
    
         // 调用同一方法,打印cook ,waiter类
    
         get(coll);
    
         get(col2);
    
     
    
      }
    
     
    
           //<? extends emp>泛型上线   <? super emp> 下线  至少是emp
    
      public static void get(Collection<? extends emp> col) {
    
    /*就是extends表示必须是继承Emp的子类和Emp才能传过来;
    
    super意思是Emp是这个父类最底层的子类,只能是Emp的父类们 (父类,爷爷类)和它自己Emp才能传过来*/
    
         Iterator<?> it = col.iterator();
    
    /*//Collection<? extends Emp>这里是传的继承Emp的子类及其Emp;是上限的意思;上限时Emp
    */
    
         while (it.hasNext()) {
    
    /*Collection<? super Emp>这里传的是Emp的父类及其Emp;是下限的意思;下限时Emp*/
    
           System.out.println(it.next());
    
    //因为不设置上下线有通配符?存在所以传什么类都行,这样就进行了限制
    
         }
    
     
    
      }
    
    }

     

    1.1      泛型限定

    上述打印集合的功能,看似很强大,可以打印任意集合,可是问题也来了。如果想要对被打印的集合中的元素类型进行限制,只在指定的一些类型,进行打印。怎么做呢?

    要解决这个问题,我们就要学习泛型的限定。

    限定泛型的上限:

    格式:? extends E

    ? 代表接收E类型或者E的子类型的元素

    例如,泛型限定为:? extends Person

    则 ? 代表接收Person类型或者Person子类型的元素

    限定泛型的下限:

    格式:? super E

    ? 代表接收E类型或者E的父类型的元素

    例如,泛型限定为:? super Student

    则 ? 代表接收Student类型或者Student父类型的元素

  • 相关阅读:
    支持stl容器的gdb自定义命令
    Thrift辅助类,用于简化Thrift编程
    Linux上获取CPU Core个数的实现
    第54课 被遗弃的多重继承(下)
    第53课 被遗弃的多重继承(上)
    第52课 C++中的抽象类和接口
    第51课 C++对象模型分析(下)
    第50课 C++对象模型分析(上)
    第49课 多态的概念和意义
    第48课 同名覆盖引发的问题
  • 原文地址:https://www.cnblogs.com/layuechuquwan/p/11428550.html
Copyright © 2011-2022 走看看