Collection和泛型

 ## Collection 
    - 集合:集合是java中提供的一种容器,可以用来存储多个数据。
    集合和数组既然都是容器,它们有啥区别呢?
    - 数组的长度是固定的。集合的长度是可变的。
    - 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。
    *集合框架:
        集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map,
        - Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set。
        其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类有java.util.ArrayList和java.util.LinkedList,
              Set接口的主要实现类有java.util.HashSet和java.util.TreeSet。
        *目标:
                1.会使用集合存储数据
                2.会遍历集合,取数据
                3.掌握每种集合的特性
                
        *Collection接口
            定义了所有单列集合中共性的方法
            所有的单列集合都可以使用共性方法
            没有带索引的方法
                包含了list与set接口
        *list接口:
            1.有序的集合(存取元素的顺序相同)就是说存的是123,取还是123.
            2.允许存储重复的元素
            3.有索引可以使用普通的for循环遍历
            包括:    Vector ArrayList LinkedList
                  (基本不用了)

        *set接口:
            1.不允许存储重复元素
            2.没有索引(不能使用普通for循环遍历)
            3.无序的集合(存取元素的顺序有可能不一致)
                包括TreeSet  HashSet    
            
            4. LinkedHashSet是有序的集合
                        
                
    *Collection中的常用方法
    所有单列集合最顶层的接口,里面定义了所有单列集合共性的方法
        public boolean add(E e):  把给定的对象添加到当前集合中 。
        public void clear() :清空集合中所有的元素。
        public boolean remove(E e): 把给定的对象在当前集合中删除。
        public boolean contains(E e): 判断当前集合中是否包含给定的对象。
        public boolean isEmpty(): 判断当前集合是否为空。
        public int size(): 返回集合中元素的个数。
        public Object[] toArray(): 把集合中的元素,存储到数组中。
        
## Iterator迭代器(遍历单列集合)
    *java.util.Iterator,Iterator接口:主要用于迭代访问(遍历)元素,因此Iterator对象也被称为迭代器.
    *迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,
            如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。    
    *获取迭代器:public Iterator iterator(){}    
        方法返回的就是迭代器的对象
        Iterator it = 对象.iterator();
    *迭代器的使用步骤:
        1.使用集合中的方法iterator()获取迭代器的实现类对象,并接收
        2.使用hasNext()判断
        3.使用next()获得
        
    
    *Iterator接口中的常用方法    
            *public E next():返回迭代的下一个元素
            *public boolean hasNext():如果仍有元素可以迭代,则返回true
        
    *迭代器的代码实现:
        public static void main(String[] args){
            Collection <String> coll = new ArrayList<>();
            coll.add("hello");
            coll.add("hello");
            coll.add("hello");
            coll.add("hello");
            coll.add("hello");
            //迭代器是有泛型的,集合是什么泛型,迭代器就是什么泛型
            Iterator<String> it = coll.iterator;
            while(it.hasNext(){
                String string = it.next();
                System.out.println(string);
            }
            
            
        }
        *遍历时候不能增删,否则会报ConcurrentModificationException并发修改异常
        一般会另建一个集合,equals拷贝到新集合
        
        
        *jdk有一个bug:只有删除倒数第二个的时候不会报错
## 增强for循环
    *也叫foreach jdk1.5以后,不能增删,只能遍历
    *底层使用的也是迭代器,简化了迭代器的书写
    
    *格式:
        for(集合/数组的数据类型 变量名:集合名/数组名){
            sout(变量名);
        }
    *增强for循环必须有被遍历的目标,目标只能是Collection或者是数组.只能作为遍历    
        
## 泛型
    *是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型
    *泛型也可以看做是一个变量用来接收数据类型
    E e:Element 元素
    T t:type 类型
    *一般在创建对象的时候就会确定泛型(会把数类型作为参数传递)
    
    
    *使用泛型的好处
            *创建集合对象,不使用泛型
                好处:集合不使用泛型,默认的是Object.可以存储任意的类型
                弊端:不安全.会引发异常(在使用子类的方法时候要转型,不安全)
            
            *创建集合对象,使用泛型
                好处:1.避免了类型转换的麻烦,存储的什么类型,取出的就是什么类型
                     2.把运行时期的异常(代码运行之后会抛出的异常),提升到了编译期    
                弊端:泛型是什么类型,就必须存储什么类型的数据
        
    *定义含有泛型的类
        public class 类名<E>{
            private E name;
            public E getName() {
                return name;
            }

            public void setName(E name) {
                this.name = name;
            }
        }
    在创建对象时传递泛型的数据类型
    *定义含有泛型的方法
        修饰符 <泛型> 返回值类型 方法名(参数列表 (使用泛型){
            方法体
        }
     定义静态方法含有泛型
        修饰符 static <泛型> 返回值类型 方法名(参数列表 (使用泛型){
            方法体
        }
        
    *调用含有泛型的方法时候,传递任意类型的参数,传递什么类型的,泛型就是什么类型    
        
    public <E> E setName(E e){
        sout(e);
        return e;
    }
        
    *接口带有泛型,就是在接口名后加上泛型.
        两个方法:一个是在实现类直接定义好泛型
                 一个是在实现类也是实现接口的泛型,在实例化时候确定泛型
        
        
    *泛型通配符:?->代表任意的数据类型
        在不知道使用什么类型接受数据时候使用
        *使用方式:
            不能创建对象使用
            只能作为方法的参数使用
        泛型没有继承的概念,所以不写object而是使用?
        
    *泛型的上限限定: ? extends E 代表使用的泛型只能是E类型的子类/本身
    
    *泛型的下限限定: ? super E 代表使用的泛型只能是E类型的父类/本身
        

猜你喜欢

转载自blog.csdn.net/qq_35472880/article/details/81368005