为什么出现集合类?

    面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最

常用的一种方式


数组和集合类同是容器,有何不同?

    数组虽然也是可以存储对象,但长度是固定的,集合长度是可变得.数组中可以存储基本数据类型,集合只能存储对象.


集合类的特点

    集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象.

集合框架中的常用接口

    Collection接口中有两个子接口:

    List: 可以存放重复元素,元素存取是有序的.

    Set: 不可以存放重复元素,元素存取是无序的.先判断hashcode是否相同,如果不同,可以存放,如果相同,再判断equals方法是否相同.因此如果hashcode不同,即使equals相同也不能添加

HashSet 添加条件

    1.相同物理地址 不能重复添加

    2.不同物理地址 相同hashcode equals = false 可以添加

    3.不同物理地址 相同hashcode equals = true 不可以添加

    4.不同物理地址 不同hashcode equals = false 可以添加

    5.不同物理地址,不同hashcode equals = true 可以添加

总结:set集合不能添加重复对象 但Object类给使用者开放 hashcode 和 equals方法来让用户自己决定什么样的对象是一样的对象,所以说在对象是否相同这个规则上是没有标准的。set集合先调用hashcode方法判断对象的内存地址是否一样,如果相同再判断 equals方法的返回值是否为true 如果 地址一样 equals返回值为true则认为对象是相同的,不能添加。

    

    HashSet集合内部就是通过hashMap进行实现的,使用的是HashMap中的key部分.对象在添加进集合中时,首先会对hashcode进行处理(hashcode右移16位和自身做异或运算)得到一个经过处理的hash值,然后该值和集合的容量进行与运算,得到介于0和集合容量之间一个数字.该数字表示着数组的下标.也就是该元素应该存放在哪个元素中.

HashSet使用小技巧:

    hashSet的构造方法使用集合元素,我们可以用其他集合元素来初始化set集合从而达到消除集合中的重复元素的效果.

Set接口中常用的类

    HashSet:线程不安全,存取速度快。通过equals方法和hashCode方法来保证元素的唯一性。其内部通过HashMap实现,只关心其中的key值,对于value部分则给了默认的值PRESENT(空的Object对象)

    TreeSet: 线程不安全,可以对set集合中的元素进行排序,通过compareTo或者compare方法来

保证元素的唯一性。元素是以二叉树的形式放置的,允许存放null值

    作用:

        1.使用比较方法判断对象是否重复

        2.比较方法实现有两种

            a.自定义Comparator比较器,和TreeSet关联

            b.让javaBean实现Comparable接口,实现compareTo方法

        3.TreeSet可以容纳null元素

        4.TreeSet可以使用降序排序

            通过descendingIterator()方法得到降序迭代器实现.

        5.TreeSet默认升序排列

    TreeSet的排序方法:

        1.使用排序器(Comparator)来创建TreeSet对象 需要先创建一个Comparator对象 实现它的抽象compare方法该方法有两个参数 分别是传递进去比较的两个对象,如果返回值为负数表示第一个参数排在前面,正数则相反,返回0表示两对象相同,在存入TreeSet集合时只保留一个. 所以在用连个对象的数值属性作为排序规则时,第一个参数-第二个参数表示升序,反之则是降序.

        //实例化排序器

Comparator<Person> comparator = new Comparator<Person>(){

            public int compare(Person p1,Person p2){

                if(p1 == null){

                    if(p2 == null){

                        return 0;

                    }else{

                        return -1;

                    }

                }else{

                    if(p2 == null){

                        return 1;

                    }else{

                        return p2.getAge() - p1.getAge();

                    }

                }

            }


        };


        TreeSet<Person> ts = new TreeSet<Person>(comparator);

        Person p1 = new Person("p1",10);


        Person p2 = new Person("p2",11);

        Person p3 = new Person("p3",12);

        ts.add(p1);

        ts.add(p2);

        ts.add(p3);


        Person p; 

        for(Iterator<Person> i = ts.iterator();i.hasNext();){

            p = i.next();

            System.out.println(p!=null?p.getName():"nobody");

        }

        2.将需要排序的对象实现Comparable接口

            public int compareTo(Object o){

                    if(o!=null && o instanceof Dog){

                    return this.weight-((Dog)o).getWeight();

                }

                return -1;

            }



Map

    Map与Collecation 在集合中属并列存在,他们都是根接口.Map的特点是键值对,Map存储元素使用put方法,Collection使用add方法 Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素.Map集合中要保证唯一性.Map中所有的key元素保存在set集合中,为了保证key的唯一性,也可以使用null作为key

因为set集合是不能重复的.Map中的value是可以重复的.  Map中有三中set:EntrySet,keySet,ValueSet

    

    Map里面有一个接口Entry,其中保存了我们存放的键值对数据,可以使用 entrySet来获取所有的Entry

                            Set<Entry<String,Person>> entries = map.entrySet();

    

 通过entrySet遍历map:

wKioL1cpxXSB4R4pAAAYFlh0lmw075.png

通过keySet 遍历map:

wKioL1cpxaOyIZuoAAAXIYZ2C2k396.png

迭代注意事项:

    1.迭代器在Collection接口中是通用的,它代替了Vector类中的 Enumeration(枚举)

    2.迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException

    3.迭代器的next方法返回值类型是Object.所以要记得类型转换