java基础36 双例集合Map下的HashMap和TreeMap集合

单例集合体系:

---------| collection  单例集合的根接口
--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合中的有序不是指自然顺序,而是指添加进去的顺序与出来的顺序是一致的
------------------| ArrayList  ArrayList底层维护了一个object数组的实现的。(线程不安全),特点:查询速度快,增删速度慢。(有序,可重复)
------------------| LinkedList  LinkedList底层是使用链表结构实现的,线程不安全,特点:查询速度慢,增删速度快。(有序,可重复)
------------------| Vector(了解即可)  底层也是维护一个Object数组的实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低
--------------| Set  如果实现了set接口的集合类,具备的特点:无序,不可重复     注:集合中的无序不是指自然顺序,而是指添加元素进去的顺序与元素出来的顺序是不一致的
------------------| HashSet  底层是用于一个哈希表支持的,线程不安全,特点:存储速度块
------------------| TreeSet  底层是使用红黑树(二叉树)数据结构实现的,线程不同步(即线程不安全),不能在多线程中共享,但可以使用synchroinzedMap()方法来实现同步。特点:会对元素进行排序存储(按自然顺序)

双例集合体系:

----------| Map  双例集合的根接口。如果是实现了Map接口的集合类,具备的特点:存储的数据都是以键值对形式存在的,键不可重复,值可以重复
--------------| HashMap  底层是基于哈希表实现的,HashMap允许键和值为null,线程不安全,特点:存储速度块
--------------| TreeMap  基于红黑数(二叉树)数据结构实现的,线程不同步(即线程不安全),特点:会对元素经行排序存储
--------------| HashTable(了解即可)  线程安全


一、HashMap集合

1.1、HashMap集合的一些常用方法

    和Map集合的常用方法差不多

1.2、HashMap的存储原理

  往HasMap集合中添加元素时,首先会调用键的hashCode()方法得到元素的哈西马值,然后经过运算在哈希表找到相应存储位置
      情况1:如果算出的位置目前没有任何元素,那么该元素可以直接添加到哈希表中。
      情况2:如果算出元素的位置已经存在其他元素,那么就会调用equals方法与该元素位置已存在的元素做一次比较;如过equals方法返回值是true,那么该元素是重复元素,不允许存储;如果返回值是false,那么该元素不是重复元素,则允许存储。

和HashSet差不多(1.2或例1处)

1.3、HashMap和HashSet的区别

相同点:
    1.集合中元素都是无序,不可重复。且都要重写HashCode和equals方法进行判断比较。注:“无序”指添加元素进去(集合)的顺序与元素输出来的顺序是不一致的。指定的比较字段不可重复,但 非指定字段可重复
    2.都是线程不安全的

不同点:
    1.HashMap实现了Map接口;HashSet实现了Set接口。
    2.HashMap是以键值对的形式储存的;HashSet存储的是对象。
    3.HashMap比较快,因为使用的是唯一的键来获取对象;HashSet较HashMap来说,比较慢。
    4.HashMap是使用put()方法将元素放入map集合中;而HashSet是使用add()方法将元素放入set集合中。

1.4、实例

例1  (没有重写HashCode和equals方法的结果:“110,狗娃”这个重复元素,两个都添加进map集合中)

package com.dhb.collection;

import java.util.HashMap;

/**
 * @author DSHORE / 2018-5-30
 *
 */
class Personnal{
    int id;
    String name;

    public Personnal(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Personnal [id=" + id + ",name=" + name + "]";
    }

}
public class Demo22 {
    public static void main(String[] args) {
        HashMap<Personnal, String> map=new HashMap<Personnal, String>();
        map.put(new Personnal(110,"狗娃"),"001"); 
        map.put(new Personnal(220,"狗剩"), "002");
        map.put(new Personnal(330,"狗蛋"),"003");
        map.put(new Personnal(110,"狗娃"),"007");
        System.out.println("集合中的元素:"+map);//返回值:{Personnal [id=330,name=狗蛋]=003, Personnal [id=220,name=狗剩]=002, Personnal [id=110,name=狗娃]=001, Personnal [id=110,name=狗娃]=007}
    }
}

例2   (重写HashCode和equals方法后的结果:“110,狗娃”这个重复元素,只有一个添加进map集合中)

 1 package com.dhb.collection;
 2 
 3 import java.util.HashMap;
 4 
 5 /**
 6  * @author DSHORE / 2018-5-30
 7  *
 8  */
 9 class Personnal{
10     int id;
11     String name;
12 
13     public Personnal(int id, String name) {
14         super();
15         this.id = id;
16         this.name = name;
17     }
18     @Override
19     public String toString() {
20         return "Personnal [id=" + id + ",name=" + name + "]";
21     }
22     @Override
23     public int hashCode() {//重写hashCode方法
24         return this.id;
25     }
26     @Override
27     public boolean equals(Object obj) {//重写equals方法
28         Personnal p = (Personnal) obj;
29         return this.id == p.id;  //指定的比较字段不可重复,但,非指定字段可重复
30     }
31 }
32 public class Demo22 {
33     public static void main(String[] args) {
34         HashMap<Personnal, String> map=new HashMap<Personnal, String>(); //注:“无序”指添加元素进去(集合)的顺序与元素输出来的顺序是不一致的。
35         map.put(new Personnal(110,"狗娃"),"001"); //指定的比较字段不可重复,但,非指定字段可重复。   110是指定比较字段,狗娃不是
36         map.put(new Personnal(220,"狗剩"), "002");
37         map.put(new Personnal(330,"狗蛋"),"003");
38         map.put(new Personnal(110,"狗娃"),"007");
39         System.out.println("集合中的元素:"+map);//返回值:{Personnal [id=220,name=狗剩]=002, Personnal [id=110,name=狗娃]=007, Personnal [id=330,name=狗蛋]=003}
40     }
41 }

重写HashCode和equals方法后,例2比例1少了一个id为110的重复值

二、TreeMap集合

2.1、TreeMap集合的一些常用方法

    和Map集合的常用方法差不多

2.2、TreeMap需要注意的事项

    1.往TrreMap添加元素时候,如果元素本身具备自然顺序时,那么就按照自然顺序排列存储。
    2.往TrreMap添加元素时候,如果元素本身不具备自然顺序,那么键所属的类必须要实现Comparable接口,把键比较的规则定义在CompareTo方法中。
    3.往TrreMap添加元素时候,如果元素本身不具备自然顺序,键所属的类也没有实现Comparable接口,那么必须在创建TreeMap是传入一个比较器。

和TreeSet差不多(2.2处)

2.3、自定义比较器

    自定一个比较器只需要实现接口 Comparator<T>即可,把元素与元素之间的比较规则定义在compare方法内即可

自定义比较器的格式:
    class 类名  implements Comparator<T>{

    }

实例  (通过自定义比较器来排序存储)

 1 package com.dhb.collection;
 2 
 3 import java.util.Comparator;
 4 import java.util.TreeMap;
 5 
 6 /**
 7  * @author DSHORE / 2018-5-30
 8  *
 9  */
10 class Emp3{
11     String name;
12     int salary;
13     public Emp3(String name,int salary) {
14         this.name=name;
15         this.salary=salary;
16     }
17     @Override
18     public String toString() {
19         return "Emp [name=" + name + ",salary=" + salary + "]";
20     }
21 }
22 //自定义比较器    作用:用于根据指定字段进行比较 排序存储
23 class MyComparator1 implements Comparator<Emp3>{
24 
25     public int compare(Emp3 o1, Emp3 o2) {
26         return o1.salary-o2.salary;
27     }
28 }
29 public class Demo23 {
30     public static void main(String[] args) {
31         MyComparator1 mc=new MyComparator1();//创建比较器MyComparator1对象
32         TreeMap<Emp3, Integer> tm=new TreeMap<Emp3, Integer>(mc);
33         tm.put(new Emp3("张三",2000),1);
34         tm.put(new Emp3("李四",1000), 2);
35         tm.put(new Emp3("王五",36000),3);
36         tm.put(new Emp3("赵六",5000), 4);
37         
38         System.out.println(tm);//返回值:{Emp [name=李四,salary=1000]=2, Emp [name=张三,salary=2000]=1, Emp [name=赵六,salary=5000]=4, Emp [name=王五,salary=36000]=3}
39     }
40 }

2.4、TreeMap和TreeSet的区别

 相同点:
    1.都是无序集合(添加进去和输出来的顺序不一样),但是,存储方式都是一样的,都是按自然顺序排序存储的。
    2.都是非同步集合(线程不安全),因此他们不能在多线程之间共享,不过可以使用方法Collections.synchroinzedMap()来实现同步。
    3.运行速度都要比Hash集合慢。

不同点:
    1.TreeMap实现了Map接口;TreeSet实现了Set接口。
    2.TreeMap是以键值对的形式储存的;TreeSet存储的是对象。
    3.TreeMap是使用put()方法将元素放入map集合中;而TreeSet是使用add()方法将元素放入set集合中。

 2.5、实例  

通过实现Comparable<T>接口来 排序存储

 1 package com.dhb.collection;
 2 
 3 import java.util.TreeMap;
 4 
 5 /**
 6  * @author DSHORE / 2018-5-30
 7  *
 8  */
 9 class Emp4 implements Comparable<Emp4>{ //实现Comparable<T>接口
10     String name;//姓名
11     int salary;//工资
12     public Emp4(String name,int salary) {
13         this.name=name;
14         this.salary=salary;
15     }
16     @Override
17     public String toString() {
18         return "Emp [name=" + name + ",salary=" + salary + "]";
19     }
20     @Override
21     public int compareTo(Emp4 e) {//实现Comparable接口后,重写compareTo方法
22         return this.salary - e.salary;//用工资进行排序存储
23     }
24 }
25 public class Demo24 {
26     public static void main(String[] args) {
27         TreeMap<Emp4, Integer> tm=new TreeMap<Emp4, Integer>();
28         tm.put(new Emp4("张三",2000),1);
29         tm.put(new Emp4("李四",1000), 2);
30         tm.put(new Emp4("王五",36000),3);
31         tm.put(new Emp4("赵六",5000), 4);
32         
33         System.out.println(tm);//返回值:{Emp [name=李四,salary=1000]=2, Emp [name=张三,salary=2000]=1, Emp [name=赵六,salary=5000]=4, Emp [name=王五,salary=36000]=3}
34     }
35 }

原创作者:DSHORE

作者主页:http://www.cnblogs.com/dshore123/

原文出自:https://www.cnblogs.com/dshore123/p/9110016.html

欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

原文地址:https://www.cnblogs.com/dshore123/p/9110016.html