day08-集合【LinkedList、HashSet、Collection集合体系】

Day08 集合

1.数据结构

是用来研究如何存储数据的,也就是研究存储数据的方式的。

常见的数据结构:    
1.数组:
    使用一段连续的内存空间来存储一组数据,相邻的两个元素的地址是挨着的;
    第一个元素的地址(首地址)就是数组的地址;
    计算元素的地址的公式:数组的地址+索引*每个元素占用的空间大小;

    特点: 查询和修改数据速度快;删除速度比较慢;
2.链表:
    不是使用一组连续的内存空间存储数据的,相邻的两个数据的地址可以不是挨着的;
    在前一个元素中记录下一个元素的地址,可以通过两个元素中的地址找到下一个元素;

    特点: 查询和修改的速度慢;增删数据的速度快;
3.哈希表:
    使用一张表和复杂的算法来存储一组数据的;

    特点: 如果hash表中使用纯数组存储数据,hash算法查询数据的速度是最快的;存储的顺序不一定是你添加的顺序;
4.队列
    特点: 先进先出;
5.栈
    先压入到栈中的元素存放在栈底;
    后压入的元素存放在栈顶;
    位于栈顶的元素最先弹出栈,位于栈底的元素最后出栈;

2.LinkedList类

LinkedList集合数据存储结构是链表式结构;
操作头尾节点的方法:

    viod addFirst(E e) :在链表的第一个节点位置添加一个新元素;
    viod addLast(E e) :在链表的最后一个节点位置添加一个新元素;
    E getFirst():得到第一个元素;
    E getLast():得到最后一个元素;

    E pop():弹栈,取出栈定的元素;
    void push(E e):向栈中添加一个新的元素;
应用场景:
    1.当查询的情况比较多的时候,使用ArrayList集合;
    2.添加和删除的情况比较多时,使用LinkedList集合;
    3.当不能区分查询和添加,删除的情况那个多时,就使用ArrayList;

3.set接口

Set集合有多个子类,主要介绍HashSet、LinkedHashSet集合;

Set与List的区别:
    1.list集合中存储的元素的顺序与添加元素的顺序是一致的,set集合中存储元素的顺序和添加元素的顺序不一定是一致的;
    2.list集合中可以存储重复的元素,set集合中不能存储重复的元素;

Set接口中的方法都是从Collection接口中继承过来,没有特有的方法;

实现类:
    HashSet类
    LinkedHashSet类

4.ArrayList和HashSet 的add 方法的区别:

1.ArrayList的add方法:
      public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
      }

    永远返回true,永远添加成功,没有判断是否重复,可以添加重复的元素.

2.HashSet 的add 方法

    不能添加重复的元素,判断两个元素是否重复时调用了 hashCode()方法和equals方法;

    1. 源代码:

        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }


    2.调用hashmap的put方法:
        public V put(K key, V value) {

            ...

            // 得到元素的地址
            int hash = hash(key);

            // 得到元素在hashset集合中的索引位置
            int i = indexFor(hash, table.length);

            for (在集合中查找相同的元素 e) {

                // 判断两个对象是否一样:
                // 1.地址要一样;
                // 2.内容要一样;
                if (e.hash == hash && ( key.equals(k)) {

                    // 返回已经存在的元素
                    return oldValue;
                }
            }

            // 如果没有重复的元素
            // 集合的大小加1
            modCount++;
            // 把元素添加到集合中
            addEntry(hash, key, value, i);
            // 添加成功后返回null
            return null;
        }

    3.调用hash方法:
        得到元素的地址
        final int hash(Object k) {
            ...

            // 得到元素的地址
            h  = k.hashCode();

            ...
            return h;
        }

4.ArrayList集合判断元素是否唯一

contains方法:

    只调用equals方法来判断的;

    1. 源代码:
        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }

    2. 调用indexOf()方法:

        如果在集合中找到了一样的元素就返回元素的索引;
        如果没找到就返回-1;
        public int indexOf(Object o) {
            if (o == null) {
                ...

            } else {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }

5.HashSet集合判断元素是否唯一

contains方法:

    使用两个方法判断元素是否重复:
        equals方法和hashCode方法:

    1.源代码:
        public boolean contains(Object o) {
            return map.containsKey(o);
        }

    2.调用了hashMap的containsKey方法:
         public boolean containsKey(Object key) {
            return getEntry(key) != null;
        }

    3.调用Hashmap的getEntry方法:
         final Entry<K,V> getEntry(Object key) {
            if (size == 0) {
                return null;
            }

            // 得到传进来的那个数据的地址
            int hash =  hash(key);

            // 得到传进来的那个数据在hashset中第一次出现的索引位置
            int i = indexFor(hash, table.length);

            for (得到重复的那个元素 e) {
                Object k;
                if (e.hash == hash && key.equals(k))
                    return e;
            }
            return null;
        }

    4.调用hash方法:
        得到元素的地址
        final int hash(Object k) {
            ...

            // 得到元素的地址
            h  = k.hashCode();

            ...
            return h;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值