zoukankan      html  css  js  c++  java
  • 重踏学习Java路上_Day17(登录注册案例,Set集合,Collection集合总结,在集合中常见的数据结构)

    1:登录注册案例(理解)

    需求:用户登录注册案例。

    按照如下的操作,可以让我们更符号面向对象思想
        A:有哪些类呢?
        B:每个类有哪些东西呢?
        C:类与类之间的关系是什么呢?
        
    分析:
        A:有哪些类呢?
            用户类
            测试类
        B:每个类有哪些东西呢?
            用户类:
                成员变量:用户名,密码
                构造方法:无参构造
                成员方法:getXxx()/setXxx()
                           登录,注册
                           
                假如用户类的内容比较对,将来维护起来就比较麻烦,为了更清晰的分类,我们就把用户又划分成了两类
                    用户基本描述类
                        成员变量:用户名,密码
                        构造方法:无参构造
                        成员方法:getXxx()/setXxx()
                    用户操作类
                        登录,注册
            测试类:
                main方法。
        C:类与类之间的关系是什么呢?
            在测试类中创建用户操作类和用户基本描述类的对象,并使用其功能。
            
    分包:
        A:功能划分
        B:模块划分
        C:先按模块划分,再按功能划分
        
    今天我们选择按照功能划分:
        用户基本描述类包 cn.itcast.pojo
        用户操作接口 cn.itcast.dao
        用户操作类包 cn.itcast.dao.impl
            今天是集合实现,过几天是IO实现,再过几天是GUI实现,就业班我们就是数据库实现
        用户测试类 cn.itcast.test

    2:Set集合(理解)
        (1)Set集合的特点
            无序,唯一   (一个不包含重复元素的 collection。因为无序,所以没有索引,所以没有get(index)方法,只有list接口才有get(index))
        (2)HashSet集合(掌握)
            A:底层数据结构是哈希表(是一个元素为链表的数组)
            B:哈希表底层依赖两个方法:hashCode()和equals(),哈希表保证了元素的唯一性
              执行顺序:
                首先比较哈希值是否相同
                    相同:继续执行equals()方法
                        返回true:元素重复了,不添加
                        返回false:直接把元素添加到集合
                    不同:就直接把元素添加到集合
            C:如何保证元素唯一性的呢?
                由hashCode()和equals()保证的
            D:开发的时候,重写hashCode()与equal()代码非常的简单,自动生成即可。(如果是自己重写代码,一般是返回值=基本类型*特别值+引用类型的.hashCode(),这样生成)
            E:HashSet的子类:LinkedHashSet<E> , 特点:具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现,此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。本子类没有任何特有方法,继承自HashSet所有方法,所以可以直接用父类任何方法。哈希表保证唯一性,链表保证有序性。
            F:HashSet存储字符串并遍历 :除了不能用普通for方法,其他一样,因为set无序没有get()方法,所以不能有普通for,只能用增强for,与Iterator
            G:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素) 重写equal与hashcode方法
           
        (3)TreeSet集合
            A:底层数据结构是红黑树(是一个自平衡的二叉树),TreeMap;
            B:保证元素的排序方式
                a:自然排序(元素具备比较性)
                    让元素所属的类实现Comparable接口
                b:比较器排序(集合具备比较性)
                    让集合构造方法接收Comparator的实现类对象
            C:把我们讲过的代码看一遍即可
        (4)案例:(代码在随笔名称:TreeSet概述(源码和内部图 进行解析)
            A:获取无重复的随机数
            B:键盘录入学生按照总分从高到底输出

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

    /*
     * HashSet:存储字符串并遍历
     * 问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
     * 通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。
     * 步骤:
     *         首先比较哈希值
     *         如果相同,继续走,比较地址值或者走equals()
     *         如果不同,就直接添加到集合中    
     * 按照方法的步骤来说:    
     *         先看hashCode()值是否相同
     *             相同:继续走equals()方法
     *                 返回true:    说明元素重复,就不添加
     *                 返回false:说明元素不重复,就添加到集合
     *             不同:就直接把元素添加到集合
     * 如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。
     * 而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
     */

    HashSet add()方法源码解析:用于理解为什么set接口只允许唯一元素进入Set,而不能重复元素
    interface Collection {
        ...
    }

    interface Set extends Collection {
        ...
    }

    class HashSet implements Set {
        private static final Object PRESENT = new Object();
        private transient HashMap<E,Object> map;
        
        public HashSet() {
            map = new HashMap<>();
        }
        
        public boolean add(E e) { //e=hello,world
            return map.put(e, PRESENT)==null;
        }
    }

    class HashMap implements Map {
        public V put(K key, V value) { //key=e=hello,world
        
            //看哈希表是否为空,如果空,就开辟空间
            if (table == EMPTY_TABLE) {
                inflateTable(threshold);
            }
            
            //判断对象是否为null
            if (key == null)
                return putForNullKey(value);
            
            int hash = hash(key); //和对象的hashCode()方法相关
            
            //在哈希表中查找hash值
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                //这次的e其实是第一次的world
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                    //走这里其实是没有添加元素
                }
            }

            modCount++;
            addEntry(hash, key, value, i); //把元素添加
            return null;
        }
        
        transient int hashSeed = 0;
        
        final int hash(Object k) { //k=key=e=hello,
            int h = hashSeed;
            if (0 != h && k instanceof String) {
                return sun.misc.Hashing.stringHash32((String) k);
            }

            h ^= k.hashCode(); //这里调用的是对象的hashCode()方法

            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    }
    hs.add("hello");
    hs.add("world");
    hs.add("java");
    hs.add("world");
    -------------------------------------------------------------------------------------------------------

    HashSet子类:LinkedHashSet

    /*
     * LinkedHashSet:底层数据结构由哈希表和链表组成。
     * 哈希表保证元素的唯一性。
     * 链表保证元素有素。(存储和取出是一致)
     */
    public class LinkedHashSetDemo {
        public static void main(String[] args) {
            // 创建集合对象
            LinkedHashSet<String> hs = new LinkedHashSet<String>();

            // 创建并添加元素
            hs.add("hello");
            hs.add("world");
            hs.add("java");
            hs.add("world");
            hs.add("java");

            // 遍历
            for (String s : hs) {
                System.out.println(s);
            }
        }
    }
    --------------------------------------------------------------------------------------------------------       
    3:Collection集合总结(掌握)
        Collection
            |--List    有序(存储顺序与读取数据顺序不一致),可重复
                |--ArrayList
                    底层数据结构是数组,查询快,增删慢。
                    线程不安全,效率高
                |--Vector
                    底层数据结构是数组,查询快,增删慢。
                    线程安全,效率低
                |--LinkedList
                    底层数据结构是链表,查询慢,增删快。
                    线程不安全,效率高
            |--Set    无序,唯一
                |--HashSet
                    底层数据结构是哈希表。
                    如何保证元素唯一性的呢?
                        依赖两个方法:hashCode()和equals()
                        开发中自动生成这两个方法即可
                    |--LinkedHashSet
                        底层数据结构是链表和哈希表
                        由链表保证元素有序
                        由哈希表保证元素唯一
                |--TreeSet
                    底层数据结构是红黑树。
                    如何保证元素排序的呢?
                        自然排序
                        比较器排序
                    如何保证元素唯一性的呢?
                        根据比较的返回值是否是0来决定
                        
    4:针对Collection集合我们到底使用谁呢?(掌握)
        唯一吗?
            是:Set
                排序吗?
                    是:TreeSet
                    否:HashSet
            如果你知道是Set,但是不知道是哪个Set,就用HashSet。
                
            否:List
                要安全吗?
                    是:Vector
                    否:ArrayList或者LinkedList
                        查询多:ArrayList
                        增删多:LinkedList
            如果你知道是List,但是不知道是哪个List,就用ArrayList。
        
        如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
        
        如果你知道用集合,就用ArrayList。
        
    5:在集合中常见的数据结构(掌握)
        ArrayXxx:底层数据结构是数组,查询快,增删慢
        LinkedXxx:底层数据结构是链表,查询慢,增删快
        HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
        TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

    6.ArrayList集合的toString()方法源码解析
    代码:
        Collection c = new ArrayList();
        c.add("hello");
        c.add("world");
        c.add("java");
        
        System.out.println(c);
        
    为什么c输出的不是地址值呢?

    java.util
    类 ArrayList<E>
    java.lang.Object
      java.util.AbstractCollection<E>   -----------------这里才有toString()的实现方法
          java.util.AbstractList<E>     ----------------- 这里也没有
              java.util.ArrayList<E>    ---------------- 这里没有

        A:Collection c = new ArrayList();
            这是多态,所以输出c的toString()方法,其实是输出ArrayList的toString()
        B:看ArrayList的toString()
            而我们在ArrayList里面却没有发现toString()。
            以后遇到这种情况,也不要担心,你认为有,它却没有,就应该去它父亲里面看看。
        C:toString()的方法源码
        
            public String toString() {
                Iterator<E> it = iterator(); //集合本身调用迭代器方法,得到集合迭代器
                if (! it.hasNext())
                    return "[]";
        
                StringBuilder sb = new StringBuilder();
                sb.append('[');
                for (;;) {
                    E e = it.next(); //e=hello,world,java
                    sb.append(e == this ? "(this Collection)" : e);
                    if (! it.hasNext())
                        //[hello, world, java]
                        return sb.append(']').toString();
                    sb.append(',').append(' ');
                }
            }
           

  • 相关阅读:
    车载OS盘点及特点分析一:车载OS几大系统介绍
    CTF常用软件/工具
    汽车软件产业研究报告(2020年)
    高级加密标准(AES)分析
    工具 | CTP、SimNow、NSight、快期
    CTF之图片隐写术解题思路
    V2X和车路协同研究:5G V2X将成为数字座舱标配
    腾讯安全正式发布《IoT安全能力图谱》
    Microsoft Remote Desktop Beta 下载地址
    密码学初探|加密模式
  • 原文地址:https://www.cnblogs.com/canceler/p/4620724.html
Copyright © 2011-2022 走看看