Java常用集合ArrayList/HashMap/TreeSet

* Java 常用集合:
         * ?ArrayList 不是线程安全的,Vector是线程安全的,但是生产环境中已经不使用了。
     * 1- CopyAndWriteArrayList
     * 2- Collections.synchronizedList(List<T> list)
     * 以上,两个线程安全。
     * 1、List接口及常见实现.
     * 2、Map接口及常见实现.
     * 3、Set接口和常见实现.
     *List(父接口:Collection)常用实现类:
     *      1-ArrayList: 底层是动态数组、查找快、增删慢,默认初始容量是10、每次采用15倍的扩容。
     *      2-Vector: 和ArrayList一样,不同是是它支持线程同步。
     *      3-LinkedList: 采用双向链表结构存储数据,适用于动态地插入和删除,随机访问和遍历比较慢。它实现了Deque(双端队列)接口,因此还有队列的特性。
     *Map(顶级接口)常用实现类:
     *      1-HashMap: 底层是数组+链表+红黑树,默认初始容量是16、扩容机制:(扩容因子为0.75,每次采用2倍的扩容。
     *      2-HashTable: 线程安全,遗留类,不建议使用。
     *      3-ConcurrentHashMap: 使用比较多的一种线程安全的Map实现类,使用Synchronized关键字实现的线程安全。
     * ?HashMap ?
     *         ?请阐述HashMap的put的过程?
     *         根据Node节点K值得到数据数组()位置,当数组()的位置没有元素就put,当数组()的位有元素就链表式向尾部put,形成单链表,当链表的阈值为8时,形成树化红黑树,当红黑树的值阈值为6,形成链化单链表。
     *
     *hash(key)方法是如何实现的==如何根据K得到数组()的位置?
     *         -底层使用的位(B)运算的,数组()的位置是个Int值(下标索引值) 下标初始值,默认数据长度(16)-1得到初始下标值(15),
     *         -使用 int hashCode = key.hashCode(); 可以拿到下标值;
     *         --hash(key)方法 位运算完成后 下标长度15=它二进制 00001111; 拿hashCode的值 跟 下标15的二进制,进行'与(&)运算';(&)运算的特点是:只有参与两个数的运算都全是'1'结果才是'1'*         --核心算法公式:"key.hashCode() 得出随意插入的Int值 & (数据长度-1)"
     *         -- key.hashCode()&(n-1);
     *         -- hash(key)方法,再次,为了进可能离散,hashCode在高16^位低16^位 做了一个 | & 运算. 这样来保证分散操作。
     *         -- 最总公式: hash(key)=key.hashCode()16与低16进行异、或运算,然后跟数组的总长度 &(n-1) 运算,最终得到一个需要的hash值。
     *         -int hash = hash(key)=key.hashCode()16^16&(n-1);
     *
     *         ?为什么HashMap的容量一直是2的倍数?
     *         -因为只有参与hash(key)算法的 n-1 的值的二进制 的最后四位必须是 1111 那么进行&的分散匹配(离散运算) 无法保证最小值0最大值15; 如果不这样运算,就可能造成hash冲突的问题。?Hash冲突如何解决?
     *         -例如:16-1=15=1111       161次方=16
     *              48-1=47=101111     163次方=48
     *              144-1=143=10001111 169次方=144
     *
     *         ?HashMap是如何扩容的?
     *         -2倍扩容
     *
     *         ?扩容后元素怎么存放?大于等于8--树化红黑树,阈值8, 小于等于6--链化链表,阈值6;
     *         -扩容后,数组需要从排序,--重排序的数据只能在原下标位置,或者新下标位置=(原下标+原容量) resize()方法内做的;
     *
     *         ?HashMap链表的插入顺序? --1.7头部插入 1.8尾部插入
     *Set(父接口:Collection)常见的实现类:
     *      1-HashSet: HashSet的底层其实就是一个HashMap,只是在add的时候只使用了HashMap的key部分。(不可重复的集合类,因'K'不可重复)
     *      2-TreeSet: 可以对Set集合进行排序,默认自然排序(基本数据类型/数值数据类型)*
     *     ?自定义数据类如何在TreeSet中实现排序?
     *      -分别是采用Comparable(可比较的)接口和Comparator(比较器)来实现。
     *
     * 总结:Set集合的特点就是无序,不可重复,
     *      List集合是有序,可以重复。
     
---------------------------------------------------------------------------------------------
 * @describe TreeSet集合:可以对Set集合进行排序,默认自然排序(基本数据类型/数值数据类型)* @requirement 具体需求
 */
public class TreeSetTest {

}
class TreeSetTestStudent {
    public static void main(String[] args) {

        Student zs = new Student(20,"zs");
        Student ls = new Student(30,"ls");
        Student ww = new Student(40,"wu");

        Set<Student> set = new TreeSet<>();
        // 存储的自定义类型必须是 Comparable 类型,可有序排序。
        set.add(zs);
        set.add(ls);
        set.add(ww);

        set.forEach(student -> out.println(student.name+student.age));

    }

}
class TreeSetTestPerson{
    public static void main(String[] args) {

        Person zs = new Person(20,"zs");
        Person ls = new Person(30,"ls");
        Person ww = new Person(40,"wu");

        Set<Person> set = new TreeSet<>((o1, o2) -> {
                if(!(o1 instanceof Person)){
                    throw new RuntimeException("o1参数非法");
                }

                if(!(o2 instanceof Person)){
                    throw new RuntimeException("o2参数非法");
                }
            return o1.age- o2.age;
        });

        set.add(zs);
        set.add(ls);
        set.add(ww);

        set.forEach(person -> out.println(person.name+person.age));
    }
}

点击-源代码地址:CodeChina

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值