集合 泛型

集合: 存储对象数据 的集合容器。

单例集合

----------| Collection  单例集合 的根接口
----------------| List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。
-------------------| ArrayList ArrayList底层是使用了Object数组实现 的。 特点: 查询速度快,增删慢。
-------------------| LinkedList LinkedList底层是使用了链表数据结构实现的。特点: 查询速度慢,增删快
-------------------| Vector 底层是使用了Object数组实现 的, 实现原理与ArrayList 是一致的,但是是线程安全的,操作效率低。
----------------| Set  如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
-------------------| HashSet 底层是使用了哈希表实现 的。 特点: 存取速度快。

HashSet存储元素的原理:
     往hashSet添加元素的时候,首先会调用元素的hashCode方法得到元素的哈希码值,然后把哈希码值经过运算算出该元素存在哈希表中的位置。
    
    情况1:如果算出的位置目前还没有存在任何的元素,那么该元素可以直接添加到哈希表中。
        
    情况2: 如果算出的位置目前已经存在其他的元素,那么还会调用元素 的equals方法再与这个位置上 的元素比较一次。
    如果equals方法返回的是true,那么该元素被视为重复元素,不允许添加。如果equals方法返回 的是false,那么该元素也可以被添加。
------------------| TreeSet  底层是使用了红黑树(二叉树)数据结构实现的。 特点: 对集合中的元素进行排序存储、。

TreeSet要注意的事项:
    1. 往TreeSet添加元素 的时候,如果元素具备自然顺序的特点,那么TreeSet会根据元素 的自然顺序特性进行排序 存储。
    2. 往TreeSet添加元素 的时候,如果元素不具备自然顺序的特点,那么元素所属的类就必须要实现Comparable接口,把比较的规则定义在CompareTo方法上。
    3. 往TreeSet添加元素 的时候,如果元素不具备自然顺序的特点,那么元素所属的类就也没有实现Comparable接口,那么在创建TreeSet对象的时候必须要传入比较器对象。
    
    比较器 的定义格式:
        
            class 类名 implements  Comparator{
            }

双列集合
    ----------| Map 存储的数据都是以键值对的形式存在的,键可以不重复,值可重复。
    -------------| HashMap 底层也是使用了哈希表实现的。
    -------------| TreeMap 底层也是使用了红黑树数据结构实现的。

     

ArrayList arr=new ArrayList();//Object
        arr.add("e");
        arr.add("longText");
        arr.add(1);
        for(int i=0;i<arr.size();i++){
            String str=arr.get(i);
            System.out.println(str.toUpperCase()));//编译通过运行错误
        }//声明泛型ArrayList<String> list=new ArrayList<String>(),将运行时出现的问题提前到编译时,避免强制类型转换
        //System.out.println(arr.get(1) instanceof Integer);
        
ArrayList<Sheep> arr = new ArrayList<Sheep>();
//声明好泛型类型之后,集合中只能存放特定类型元素
//泛型类型必须是引用类型,也就是说集合不能存储基本数据类型 ArrayList<Integer>不能是ArrayList<int>

    public static void main(String[] args) {
        String[] arr=new String[]{"xx","yy","zz"};
        
        List<String> list=new ArrayList<String>();
        list.add("a");list.add("b");list.add("c");
        
        Set<String> set=new HashSet<String>();
        set.add("d");set.add("e");set.add("f");set.add("d");
        
        for(String str:set){//arr list set
            System.out.println(str);
        }
        for(Iterator<String> iter=list.iterator();iter.hasNext();){
            System.out.println(iter.next());
        }
        
        Map<String,String> map=new HashMap<String,String>();
        map.put("aa","AA");
        map.put("bb", "BB");
        map.put("cc", "CC");
        for(Entry<String,String> entry:map.entrySet()){
            System.out.println(entry);
        }
        for(String key:map.keySet()){
            System.out.println(key+" = "+map.get(key));
        }
        for(String value:map.values()){
            System.out.println(value);
        }
        
    }
    
    自定义泛型:一个数据类型的占位符
    需求:写一个函数,调用者传递什么类型的变量,该函数就返回什么类型的变量?使用泛型方法,当一个类中有多个函数声明了泛型,那么该泛型的声明可以声明在类上。
    泛型方法:public static <T> T getData(T data){return data;}//    修饰符    <声明自定义泛型> 返回类型 函数名(形参列表){}
    泛型类:    
        class MyList<T>{
            Object[] arr=new Object[10];//
            int index=0;
            public void add(T o){
                arr[index++]=o;
            }
        }
        public class demo{
            MyList<String> list=new MyList<String>();
            list.add("abc");
            MyList listT=new MyList();
    1. 在类上自定义的泛型的具体数据类型是在创建对象的时候指定的。
    2. 在类上自定义了泛型,如果创建该类的对象时没有指定泛型的具体类型,那么默认是Object类型。
        }
        
class Son extends Father<String>{    
    //子类指定了具体的类型
}
//子类也需要使用泛型
class Son3<T> extends Father<T>{
}
    
interface Inter<T> {
    void print(T t);
}
// 实现不知为何类型时可以这样定义
class MyInter<T> implements Inter<T> {
    public void print(T t) {
        System.out.println("myprint:" + t);
    }
}
//使用接口时明确具体类型。
class MyInter2 implements Inter<String> {}

------------------

集合元素:List:ArrayList,LinkList,Vector    Set:HashSet,TreeSet  Map:HashMap,TreeMap
//像HashSet中添加元素时,会调用元素的hashCode方法计算哈希值算出该元素在哈希表中的位置,若无则添加元素,若有调用equals()判断,相等不添加,不想等添加
        HashSet<Person> set = new HashSet<Person>();
        set.add(new Person(110,"狗娃0"));
        set.add(new Person(110,"狗娃1"));
class Person{        
    public int hashCode() {
        return this.id;
    }
    public boolean equals(Object obj) {
        Person p = (Person)obj;
        return this.name == p.name;
    }
}

 迭代器在迭代的 过程中不能使用集合对象修改集合中的元素个数,可以用iter.remove()
for(String item : set){//底层用迭代器方式实现
            System.out.print(item+",");
            //错误 set.add("test");
        }

------------

运行时异常与编译时异常 .RuntimeException 如 数组下标越界
用了throws就不用try-catch了,throws会自动捕捉异常然后抛出
在catch中throw new RuntimeException的,是为了中断程序,因为runtime的异常会中断程序,不再运行下去

你可能感兴趣的:(集合,泛型)