码迷,mamicode.com
首页 > 其他好文 > 详细

集合概论

时间:2015-09-05 16:10:46      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

集合

    1 集合的作用
        集合是来保存对象,以及对象之间关系的一个容器.
        保存:将所有的元素在底层转换为object来保存。
        读取:通过迭代器来将元素列出来,再通过for,while等方法来遍历读取。

    2 不同类型的集合分别保存了对象的种类,以及关系?
        Array数组:保存了自然数字和对象的关系-->数组-->本质保存的是对象间的顺序关系。
        List(ArrayList,LinkedList):顺序和对象之间的关系,数组/链表。
        Set(HashSet,SortedSet):只保存对象,没有保存关系。
        Map(HashMap,TreeMap):保存的是对象和对象间关系,数组+链表。


    3 对象
        1 有对象必须先有类,类实例化以后成为对象,一个类可以有多个对象。
        2 所有的对象的类都有一个根类:Object
        3 他们对应的内存结构:
            类: 保存在静态代码段中,有自己唯一的地址。
            对象: 保存在堆内存中,每个对象有自己唯一的地址。


    4 对象根类的内容--Object的内容
        equals():Object中的equals()比较的是对象的内存地址,对象的内存地址是对象的属性(是对象内部的一个属性,不是外部关系)。
        hashCode():对同一个对象,在一次生命周期(一次执行)中,必须产生相同的结果。
        但是对不同的两个对象,在同一个生命周期(一次执行)中,不要求一定产生不同的结果。可以产生相同的结果,也就是说,两个对象可以有相同的hashCode 。
        toString():就是返回程序员想要告诉别人,他对这个对象的描述。
        getClass():返回运行时,某个对象对应的类。

    5 容器的属性:

        Array():是大小是固定的,并且只能保存同一类型的元素,一维里面,只能保存基本类型,或者对象。
        集合:大小是不固定的,可以随用随扩充
            我们说的集合保存任意数据类型,但是,本质不是的,是我们在保存的时候,把所有的数据类型都自动转换成了Object,所有数据的数据类型都丢失了(子类特有的属性和方法,不过不进行向下转型,是访问不到的),都只保存了Object类型的属性。当我们多态时候,父类(Object)引用,指向了子类(实际类的)对象。因此我们只能看到我们就只能看到Object的属性。
            本质上,也和数组一样,只能保存同一种对象,只是转型了而已。

    6 Map概述

        Map集合定义了对象和对象之间的关系,一个对象作为键,,一个对象作为值。
        对象有内存地址,还有对象值。
        对象有对应的类,类也有内存地址。

        问题在于,如何合适装进去,又如何正确的取出来的问题,装的是多个对象之间的关系,这些对象有的是同一个类的,有的是不同的类的
        做键(Key)的那个对象的那个对象很关键,它是完成这些的关键所在。

        (1) Map的数据结构

       底层还是一个数组,大小是不变的,数组的值,(是一个对象对应的类的内存地址),本质上,要看你自定义的类怎么重写的hashCode方法。

        HashMap 的key 无序不可重复。
        HashSet:无序不可重复。
        底层的数据结构:
            hash表/散列表:本质数组里面保存单向链表。
            hashCode():叫hash函数,也叫散列函数。
            hash函数里面的算法就叫hash算法。

            (2)Entry:单向链表
                单向链表的节点四部分组成(增删快)
                key
                value
                Entry<key,value> next
                final int hash;

                这个值是第一个单向列表的键,可以看做数组的下标。

           (3) 执行流程:
                Map m = new HashMap()      在内存中开辟16个数组的内存空间
                put("100","jack")      调用100这个字符串对象对应的String类的地址,然后hashcode(),作为第一个单向链表的在数组中的下标值为这个单向链表,并且单向链表中的每个节点都有四个值(key,value,Entry<key,value>next,final in hash)。
                其中hash值都是相等的,因为类只会加载一次,内存地址肯定是相等的,hashcode()以后的值肯定也是相等的。
                hashcode():有一句话,不相等的两个对象生成的是两个不同的hash码,这个是通过对象内部的内存地址来实现的。
                hashCode()方法,是每个类自定义的。


       (4) 设立Map的原因:       

        Array:查询快,更改慢。
        Linked:链表查询慢,更改快。
        为了一种查询和更改都比较快数据结构了,于是有了Map 。
        hash表:Array作为底层,然后里面装的数据是个链表,这样就是形成了Map 。


        Map是两个对象映射的集合:每个链表中的元素是两个对象以及他们的关系。
        也就是说,链表中的节点就是我们真正保存的元素,其中一个对象作为键,一个对象作为值。
        我们如何划分链表的标准:
         将元素放进去
            用第一个链表节点元素中作为键那个对象,进行hashCode()运算,hashCode()这个函数在Object默认是用对象的内存地址行hash返回一个整数值,但是,类库程序员,可以再自己的作为键那个对象中重写hashCode()方法,通过不同的属性生成hash码.然后把这个hash码作为数组的下标,不同的下标放到不同的数组位置上。
            具体的步骤为:我们在往Map集合中放两个对象的键值对的时候,先把作为键的那个对象调用它自身的hashCode()的方法,返回一个整型hash码,然后我在调用他自己的equals()函数去数组中比对下标,如果已经有了这个下标,我们就把这个键值对加在这个下表对应链表的尾部();如果没有这个下标,我们就把这个键值对放到新的数组位置上,并且把这个hash值作为数组的下标。

          将元素拿出来
            如果我们的想把A这个对象放进去,我们先拿这个对象,调用它自身的hashcode()方法,生成一个hash值,然后我们调用equals()方法,去数组下标中挨个比对,如果equals()不上,就说明没有,如果有那就拿出来。
            如果我想知道,我们现在有O1-->O2这个映射关系,我想知道Map中有没有。
            先调用O1的hashCode(),然后数组中equals(),如果有,然后在链表中,调用equals()去比对,这里的equals()怎么去比对,也是类库程序员自己规定的,可以按照你的需求,随意的写。

            注意:map中,要的不是你的唯一性,要的是读写和更改的速度。
            所以是你的hash函数,最终的目的,是尽可能的均匀分布在每一个的链表中,也就是每个桶位上的链表的数据量,尽量相同。

    欢迎观看阿童木与小丸子的博客:http://www.cnblogs.com/atongmyuxiaowanzi/

 

集合概论

标签:

原文地址:http://www.cnblogs.com/atongmyuxiaowanzi/p/4782940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!