Day 18

Set接口:

1. 无序(添加和取出的顺序不同),没有索引, 但是取出的顺序是固定的

2. 不允许有重复的元素,可以包含一个null

 

 

常用方法:

因为set接口也实现了collection接口,所以和collection接口的方法一样

 

遍历方式:

1.iterator

2.增强for

3.因为没有索引,所以不能用普通for

 

HashSet:

HashSet底层是HashMap;

 

hashset.add(new Dog("tom"));

hashset.add(new Dog("tom")); //可以添加

 

hashset.add(new String("hsp"));

hashset.add(new String("hsp")); //无法添加

 

HashMap的底层是 数组+链表+红黑树

当hashset添加元素时,先得到hash值,之后转成table 中的 索引值

查看这个 table[index] 位置上有没有元素,

如果没有,直接加入,

如果有,调用equals方法(考虑是否被重写),如果相同则放弃添加,如果不同就添加到该位置上的链表的末尾

如果一条链表的个数到达TREEIFY_THRESHOLD( 默认是8 ),   并且 table 大小 >=  MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树TreeNode)

 

HashSet 的 扩容 和 转红黑树 机制

1. 第一次添加时,table数组扩容到16, 临界值 16 * 0.75(loadFactor 加载因子) = 12;

2. 当table数组使用到了12个时,就会扩容2倍(16 * 2),新的临界值就是 32 * 0.75 = 24,以此类推;

3. 如果一条链表的个数到达TREEIFY_THRESHOLD( 默认是8 ),   并且 table 大小 >=  MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树); 

  如果一条链表的个数达到8个,但是table大小没到64, 那么就仍然采用数组扩容机制。

 

 

 

 

LinkedHashSet:

继承HashSet, 实现Set接口

LinkedHashSet 底层是 LinkedHashMap, 底层维护一个数组和双向链表

LinkedHashSet 加入顺序和取出顺序相同

第一次添加时,table[] 数组直接扩容到16,数组类型是 HashMap$Node;   存放的节点类型是 LinkedHashMap$Entry

 

 

Treeset:

底层是Treemap

1.当使用无参构造器创建对象时,是无序的!

2. 使用带有comparator参数的构造器,可以实现排序

    Treeset treeset = new Treeset(new comparator(){

    public int compare(Object o1, Object o2){

       return ((String) o1).compareTo((String) 02);

    }

  })

 

 

Map:

 

Map 和 Collection 是同级的,Collection是单列集合, Map是双列集合(保存的是key-value 键值对)

HashMap:

是无序的

Map中的key和value可以是任意引用类型的数据,会封装到HashMap$Node对象中

Map中的key不允许重复,如果key相同,相当于替换

Map中的key 和 value 都可以为 null, 但key只能有一个null

通常用String作为map的key,不是必须,只要是Object子类都可以

key 和 value之间存在一对一关系,即通过key总能找到对应的value

map.get(key);   //返回对应的value

 

Map接口的常用方法:

 

 

1. map.put();

2. map.remove();

3. map.get();

4. map.size();

5. map.isEmpty();

6. map.clear();

7. map.containsKey();

8. map.containsValue();

9. map.keySet();

 

 

 

HashTable:  Map接口的实现子类, 和hashmap是平级的关系

存放的元素是 key-value

key 和 value都不能为null,否则抛出空指针异常

hashtable是线程安全的,hashmap是线程不安全的

hashtable底层维护一个 Hashtable$Entry[]  初始化大小为11, 临界值threshold = 11 * 0.75 = 8;(超过8个才扩容)

扩容机制:  向左位移一位( *2) + 1;

 

 

Treemap:

使用默认构造器创建对象时,是无序的

 

 

Properties: Hashtable 的 子类,间接实现了Map接口

key和value不能为null

存取顺序不同

properties 通常用于从 配置文件  xxx.properties 文件中,加载数据到Properties对象中,并进行读取和修改

properties.put(key, value);

properties.remove( key);

properties.get(key);

properties.getProperties(key);

 

 

如何选择集合实现类:

1: 先判断 存储类型( 一组对象, 一组键值对)

2: 一组对象(单列集合): Collection接口

  允许重复: List

      增删多:LinkedList(底层是双向链表)

      改查多:ArrayList(Object类型的可变数组)

  不允许重复:Set

      无序:Hashset(底层是hashmap,即:数组+链表+红黑树)

      排序:TreeSet

3.一组键值对(双列集合):Map接口

  键无序:Hashmap(底层是 数组+链表+红黑树)

  键排序:Treemap

  键插入和取出顺序一致:LinkedHashMap

  读取文件:Properties

 

 

Collections 工具类:

Collections.reverse( List );

Collections.shuffle( List );

Collections.sort( List );   //自然排序, 默认生序

Collections.sort( List, comparator);  

Collections.swap( List, index1, index2 );  

Collections.max( List );   //根据自然排序,返回最大元素

Collections.max( List, comparator);  

Collections.frequency( List, value );  //返回value在list中出现的次数

Collections.copy( dest, source );  // 注意! 使用该方法前,必须先给dest赋值,个数和source的长度一样。 

Collections.replaceAll( list, oldVal, newVal );  //用newVal替换oldVal

 

posted @ 2021-10-03 23:28  Shawn_T  阅读(51)  评论(0)    收藏  举报