Java 基础巩固(二)

100 阅读1分钟

一、Set 集合

1.1 LinkedHashSet

  • LinkedHashSet 是HashSet的子类
  • 底层:数组 + 双向链表
  • LinkedHashSet 不允许添加重复元素
  • LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
  • 源码分析:
    • 用 after 和 before 表示前一个结点和后一个结点,所以是双向链表
    • 和HashSet底层差不多,只是添加了双向链表维持序列

1.2 TreeSet

  • 自动排序
  • 里面只能存放同一类型的值

二、Map 集合

2.1 HashMap

  • key 不允许重复
  • value 可以重复(替换机制)
  • 无序
  • 将keySet放入Set中,Vlues放入Collection中,Set和Collection指向HashMap$Node image.png

2.2 Map 接口遍历方法

  • containsKey:查找键是否存在
  • keySet :获取所有键
  • entrySet:获取所有关系
  • values:获取所有值

案例:Map 遍历的所有方式

public static void main(String[] args) {
    Map map = new HashMap();
    map.put("no1", "lyq");
    map.put("no2", "zs");
    
    // 第一组:先取出所有的 key,通过 key 取 value
   //  Set set = map.keySet();
   // (1) 增强 for
   // for (Object o : set) {
   //     System.out.println(o + "-" + map.get(o));
   // }
   // (2) 迭代器
   // Iterator iterator = set.iterator();
   // while (iterator.hasNext()) {
   //     Object next =  iterator.next();
   //     System.out.println(next + " - " + map.get(next));
   // }

    // 第二组:取出所有的 values
    Collection values = map.values();
    // 这里可以使用所有的 Collection 使用的遍历方法
    // (1) 增强 for
    // 取出所有 value
    // for (Object o : values) {
    //    System.out.println(o);
    // }
    // (2) 迭代器
       // Iterator iterator = values.iterator();
       // while (iterator.hasNext()) {
       //     Object next =  iterator.next();
       //     System.out.println(next);
       // }

    // 第三组:通过 EntrySet 来获取 k-v
    // (1) 增强 for
    Set entrySet = map.entrySet();  // EntrySet<Map.Entry<K,V>>
    for (Object entry : entrySet) {
        // 向下转型 Map.Entry
        Map.Entry m = (Map.Entry) entry;
        System.out.println(m.getKey() + " - " + m.getValue());
    }

    // (2) 迭代器
    Iterator iterator = entrySet.iterator();
    while (iterator.hasNext()) {
        Map.Entry next = (Map.Entry) iterator.next();
        System.out.println(next.getKey() + " - " + next.getValue());
    }
}

2.3 HashMap 小结

  • Map接口常用实现类:HashMap、HashTable
  • key 不能重复,底层使用 Set 存放,value 可以重复,底层使用 Collection 存放
  • 如果添加相同 key, 相当于修改了原来的值
  • 和 HashSet 一样,不保证顺序,因为底层是 hash 表的方式存储
  • HashMap 线程不安全,方法没有 synchronized 修饰
  • jdk8,HashMap 底层为:数组 + 链表 + 红黑树, jdk7没有红黑树
  • 底层剖析:
    • HashMap底层维护了Node类型的数组table,默认为null
    • 当创建对象时,将加载因子(loadfactor)初始化为0.75.
    • 当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key和准备加入的key相是否等,如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。
    • 第1次添加,则需要扩容table容量为16,临界值(threshold)为12 (16*0.75)
    • 以后再扩容,则需要扩容table容量为原来的2倍(32),临界值为原来的2倍,即24,依次类推
    • 在Java8中,如果一条链表的元素个数超过TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN TREEIFY CAPACITY(默认64).就会进行树化(红黑树)

2.4 HashTable

2.4.1 HashTable 特点介绍

  • HashTable 线程安全
  • 使用方法和 HashMap 一样
  • key 和 value 都不能为空

2.4.2 HashTable 底层分析

  1. 底层有数组 HashTable$Entry[],初始化大小为 11
  2. 临界值 threshold 8 = 11 * 0.75
  3. 按照 int newCapacity = (oldCapacity << 1) + 1 的大小扩容,例如 11 扩容 = 23

2.5 TreeMap

  • 键排序,值不排序

三、Collections 工具类

  1. reverse(List) :反转顺序
  2. shuffle(List):随机排序
  3. sort(List):升序排序
  4. swap(List, i, j):将list集合中的 i 和 j 交换
  5. Object max(Collection) :返回最大值
  6. Object min(Collection):返回最小值
  7. int frequency(Collection, Object):返回集合中指定元素出现的次数
  8. void copy(List dest, List src):复制dest 到 src 中
  9. boolean replaceAll(List list, Object oldVal, Object newVal):将 list 中所有的 oldVal 替换成 newVal