简单分析一下集合中LinkedHashMap 、weakHashMap 、TreeMap 、HashSet、LinkedHashSet、treeSet的特点

1.LinkedHashMap的特点

(1)LinkedHashMap继承了HashMap ,是基于HashMap和双向链表来实现的。
实现了Clonable ,serialiable(可序列化),map接口;
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>  
{
}
(2)提供了AccessOrder参数,用来指定LinkedHashMap的排序方式,accessOrder =false -> 插入顺序进行排序 ,
accessOrder = true -> 访问顺序进行排序。
(3)LinkedHashMap存取数据,还是跟HashMap一样使用的Entry[]的方式,双向链表只是为了保证顺序。
(4)LinkedHashMap是线程不安全的。

LinkedHashMap的适用场景:
存储的数据是键值对,且需要保证数据按插入顺序有序的话使用

2.weakHashMap的特点

WeakHashMap 继承于AbstractMap,实现了Map接口。
    和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和值都可以是null。
   不过WeakHashMap的键是“弱键”。在 WeakHashMap 中,当某个键不再正常使用时,会被从WeakHashMap中被自动移除。
更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。
某个键被终止时,它对应的键值对也就从映射中有效地移除了。
    这个“弱键”的原理呢?大致上就是,通过WeakReference和ReferenceQueue实现的。
WeakHashMap的key是“弱键”,即是WeakReference类型的;ReferenceQueue是一个队列,
它会保存被GC回收的“弱键”。
实现步骤是:
    (1) 新建WeakHashMap,将“键值对”添加到WeakHashMap中。
           实际上,WeakHashMap是通过数组table保存Entry(键值对);
    每一个Entry实际上是一个单向链表,即Entry是键值对链表。
   (2) 当某“弱键”不再被其它对象引用,并被GC回收时。在GC回收该“弱键”时,
    这个“弱键”也同时会被添加到ReferenceQueue(queue)队列中。
   (3) 当下一次我们需要操作WeakHashMap时,会先同步table和queue。table中保存了全部的键值对,
    而queue中保存被GC回收的键值对;同步它们,就是删除table中被GC回收的键值对。
   这就是“弱键”如何被自动从WeakHashMap中删除的步骤了。
特点:当插入weakHashMap的数据,随着时间的推移,存储的数据会消失,本质是数据被垃圾回收器回收了


Java的四种对象引用:
强引用:
Object o = new Object();   一般通过new创建的对象的引用就是强引用

一个对象如果只有强引用,那么垃圾回收器不会回收它,即使内存不足的情况下,JVM宁愿抛出异常,也不会回收强引用所作用的对象。
只有当没有任何对象指向它时JVM将会回收。


软引用:
public class SoftReference<T> extends Reference<T> {...}
如果一个对象只有软引用,若内存充足的情况下,当发生垃圾回收器回收时,不会回收该软引用对象,若内存不足时,发生垃圾回收会对该引用对象回收。
一般Java中提供的SoftReference<>来处理软引用


弱引用:
public class WeakReference<T> extends Reference<T> {...} Java中提供WeakReference<>来处理弱引用
如果一个对象只有弱引用,无论内存是否充足,JVM只有发生垃圾回收,改引用所作用的对象都会被回收掉。
需要注意的是:由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。


虚引用:
虚引用并不会决定对象的回收周期,如果一个对象持有虚引用,在任何时候都有可能被JVM回收
Java中提供的PhantomReference<>来处理


从上往下引用越来越低

3.TreeMap的特点

数据按照特定规则排序
TreeMap底层实现用了红黑树

 红黑树顾名思义就是节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡。
对于一棵有效的红黑树二叉树而言我们必须增加如下规则:

       1、每个节点都只能是红色或者黑色

       2、根节点是黑色

       3、每个叶节点(NIL节点,空节点)是黑色的。

       4、如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。

       5、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

TreeMap中同时也包含了如下几个重要的属性:

//比较器,因为TreeMap是有序的,通过comparator接口我们可以对TreeMap的内部排序进行精密的控制
        private final Comparator<? super K> comparator;
        //TreeMap红-黑节点,为TreeMap的内部类
        private transient Entry<K,V> root = null;
        //容器大小
        private transient int size = 0;
        //TreeMap修改次数
        private transient int modCount = 0;
        //红黑树的节点颜色--红色
        private static final boolean RED = false;
        //红黑树的节点颜色--黑色
        private static final boolean BLACK = true;

       对于叶子节点Entry是TreeMap的内部类,它有几个重要的属性:

    //键
        K key;
        //值
        V value;
        //左孩子
        Entry<K,V> left = null;
        //右孩子
        Entry<K,V> right = null;
        //父亲
        Entry<K,V> parent;
        //颜色
        boolean color = BLACK;

Comparable和Comparator的区别?

相同点:
都是JAVA的接口,用来自定义类的比较大小的

使用不同:
 
 Comparator定义在class的外部
 Comparable定义在class的内部

提供接口不同:
   
实现Comparable接口要覆盖compareTo方法

实现Comparator需要覆盖 compare 方法
用Comparable 简单,只要实现Comparable接口的对象直接就成为一个可以比较的对象,但是需要修改源代码,
用Comparator 的好处是不需要修改源代码,而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了,并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象

4.HashSet的特点

定义:
HashSet <E>:存储的是单个泛型元素
extends AbstractSet<E>:继承自AbstractSet,实现Set接口时需要实现的工作量大大减少了
implements Set<E>:实现了Set接口,提供了所有可选的 Set 操作
implements Cloneable:可以调用 clone() 方法来返回实例的 field-for-field 拷贝
implements Serializable:可以序列化

构造方法:
常用构造方法
public HashSet():实际上就是构造一个空的HashMap,然后赋值给 map 字段
public HashSet(Collection<? extends E> c):构造一个包含指定集合中所有元素的新set
public HashSet(int initialCapacity, float loadFactor):构造一个新的空set,其底层HashMap实例具有指定的初始容量和加载因子
public HashSet(int initialCapacity):构造一个新的空set,其底层HashMap实例具有指定的初始容量和默认的加载因子 (0.75)

特殊构造方法
这个构造方法是一个包私有 (package private) 的方法,可以看到它的修饰符不是 public
该方法仅用于构造 LinkedHashSet,创建的是 LinkedHashMap 而非之前的 HashMap,用于维护 Set 内元素的顺序
在 LinkedHashSet 进行初始化时,通过增加 dummy 参数来调用该方法
HashSet(int initialCapacity, float loadFactor, boolean dummy)
{
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

特点:
    无序性
    唯一性(允许使用null)
    本质上来讲就是hashmap
    需要重写hashcode()方法和equals()方法(这是废话,是个集合类都需要重写)
    HashSet没有提供get()方法,同HashMap一样,因为Set内部是无序的,所以只能通过迭代的方式获得

HashSet如何将hashMap的键值对转化成单个值处理?
// HashSet的底层就是一个HashMap实例
private transient HashMap<E,Object> map;

// HashMap是保存键值对的,而HashSet实际上只想保存key
// 因此创建一个PRESENT表示所有的value
private static final Object PRESENT = new Object();
K为我们添加的参数,V为一个Object的定值

HashMap的key=HashSet的对象,
HashMap的value=HashSet中定义的一个统一常量private static final Object PRESENT = new Object()。
也就是说,在hashset中,我们用add方法添加元素时,传给底层hashmap实例的还是键值对(两个对象),
只不过key直接就是对象元素本身,而value则是一个object常量(这就是让我们把这个value忽略掉,当成只传了一个对象)


应用场景:
    数据去重


5.LinkedHashSet的特点

重复性:数据不能重复
null值:可以存储null值
顺序性:插入有序

LinkedHashSet的底层实现是LinkedHashMap

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
注意:当前的HashSet构造函数不能被直接调用


6.TreeSet的特点

TreeSet的底层实现是TreeMap

1、不能有重复的元素;
2、具有排序功能;
3、TreeSet中的元素必须实现Comparable接口并重写compareTo()方法,TreeSet判断元素是否重复 、以及确定元素的顺序 靠的都是这个方法;
①对于Java类库中定义的类,TreeSet可以直接对其进行存储,如String,Integer等,因为这些类已经实现了Comparable接口);
②对于自定义类,如果不做适当的处理,TreeSet中只能存储一个该类型的对象实例,否则无法判断是否重复。
4、依赖TreeMap。
5、相对HashSet,TreeSet的优势是有序,劣势是相对读取慢。根据不同的场景选择不同的集合。

treeSet的适用场景:
数据去重,并且按照特定规则排序

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值