JAVA深化篇_13——Map接口,HashMap及TreeMap容器详解

Map接口介绍

Map接口定义了双例集合的存储特征,它并不是Collection接口的子接口。双例集合的存储特征是以key与value结构为单位进行存储。体现的是数学中的函数 y=f(x)感念。

Map与Collecton的区别:

  • Collection中的容器,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。
  • Map中的容器,元素是成对存在的(理解为现代社会的夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
  • Collection中的容器称为单列集合,Map中的容器称为双列集合。
  • Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
  • Map中常用的容器为HashMap,TreeMap等。

Map接口中常用的方法表

方法说明
V put (K key,V value)把key与value添加到Map集合中
void putAll(Map m)从指定Map中将所有映射关系复制到此Map中
V remove (Object key)删除key对应的value
V get(Object key)根据指定的key,获取对应的value
boolean containsKey(Object key)判断容器中是否包含指定的key
boolean containsValue(Object value)判断容器中是否包含指定的value
Set keySet()获取Map集合中所有的key,存储到Set集合中
Set<Map.Entry<K,V>> entrySet()返回一个Set基于Map.Entry类型包含Map中所有映射。
void clear()删除Map中所有的映射

HashMap容器的使用

HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。

public class HashMapTest {
  public static void main(String[] args) {
    //实例化HashMap容器
    Map<String,String> map = new HashMap<>();


    //添加元素
    map.put("a","A");
    map.put("b","B");
    map.put("c","C");
    map.put("a","D");


    //获取容器中元素数量
    int size = map.size();
    System.out.println(size);
    System.out.println("---------------");


    //获取元素
    //方式一
    String v = map.get("a");
    System.out.println(v);
    System.out.println("---------------");


    //方式二
    Set<String> keys = map.keySet();
    for(String key:keys){
      String v1 = map.get(key);
      System.out.println(key+" ---- "+v1);
     }
    System.out.println("-------------------");


    //方式三
    Set<Map.Entry<String,String>> entrySet = map.entrySet();
    for(Map.Entry<String,String> entry:entrySet){
      String key = entry.getKey();
      String v2 = entry.getValue();
      System.out.println(key+" ---------- "+v2);
     }


    System.out.println("--------------------");
    //Map容器的并集操作
    Map<String,String> map2 = new HashMap<>();
    map2.put("f","F");
    map2.put("c","CC");
    map.putAll(map2);
    Set<String> keys2 = map.keySet();
    for(String key:keys2){
      System.out.println("key: "+key+" Value: "+map.get(key));
     }


    System.out.println("---------------");
    //删除元素
    String v3 = map.remove("a");
    System.out.println(v3);
    Set<String> keys3 = map.keySet();
    for(String key:keys3){
      System.out.println("key: "+key+" Value: "+map.get(key));
     }


    System.out.println("-------------------");
    //判断Key是否存在
    boolean b = map.containsKey("b");
    System.out.println(b);
    //判断Value是否存在
    boolean cc = map.containsValue("CC");
    System.out.println(cc);


   }
}

HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低。

HashMap与HashTable的区别

  1. HashMap: 线程不安全,效率高。允许key或value为null
  2. HashTable: 线程安全,效率低。不允许key或value为null

TreeMap容器的使用

TreeMap和HashMap同样实现了Map接口,所以,对于API的用法来说是没有区别的。HashMap效率高于TreeMapTreeMap是可以对键进行排序的一种容器,在需要对键排序时可选用TreeMap。TreeMap底层是基于红黑树实现的。

在使用TreeMap时需要给定排序规则:

  • 元素自身实现比较规则
  • 通过比较器实现比较规则

元素自身实现比较规则

public class Users implements Comparable<Users>{
  private String username;
  private int userage;


  public Users(String username, int userage) {
    this.username = username;
    this.userage = userage;
   }


  public Users() {
   }


  @Override
  public boolean equals(Object o) {
    System.out.println("equals...");
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;


    Users users = (Users) o;


    if (userage != users.userage) return false;
    return username != null ? username.equals(users.username) : users.username == null;
   }


  @Override
  public int hashCode() {
    int result = username != null ? username.hashCode() : 0;
    result = 31 * result + userage;
    return result;
   }


  public String getUsername() {
    return username;
   }


  public void setUsername(String username) {
    this.username = username;
   }


  public int getUserage() {
    return userage;
   }


  public void setUserage(int userage) {
    this.userage = userage;
   }


  @Override
  public String toString() {
    return "Users{" +
        "username='" + username + '\'' +
        ", userage=" + userage +
        '}';
   }


  //定义比较规则
  //正数:大,负数:小,0:相等
  @Override
  public int compareTo(Users o) {
    if(this.userage < o.getUserage()){
      return 1;
     }
    if(this.userage == o.getUserage()){
      return this.username.compareTo(o.getUsername());
     }
    return -1;
   }
}

public class TreeMapTest {
  public static void main(String[] args) {
    //实例化TreeMap
    Map<Users,String> map = new TreeMap<>();
    Users u1 = new Users("oldlu",18);
    Users u2 = new Users("admin",22);
    Users u3 = new Users("sxt",22);
    map.put(u1,"oldlu");
    map.put(u2,"admin");
    map.put(u3,"sxt");
    Set<Users> keys = map.keySet();
    for(Users key :keys){
      System.out.println(key+" --------- "+map.get(key));
     }
   }
}

通过比较器实现比较规则

public class Student {
  private String name;
  private int age;


  public Student(String name, int age) {
    this.name = name;
    this.age = age;
   }


  public Student() {
   }


  @Override
  public String toString() {
    return "Student{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
   }


  public String getName() {
    return name;
   }


  public void setName(String name) {
    this.name = name;
   }


  public int getAge() {
    return age;
   }


  public void setAge(int age) {
    this.age = age;
   }


  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;


    Student student = (Student) o;


    if (age != student.age) return false;
    return name != null ? name.equals(student.name) : student.name == null;
   }


  @Override
  public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + age;
    return result;
   }
}

public class StudentComparator implements Comparator<Student> {


  //定义比较规则
  @Override
  public int compare(Student o1, Student o2) {
    if(o1.getAge() > o2.getAge()){
      return 1;
     }
    if(o1.getAge() == o2.getAge()){
      return o1.getName().compareTo(o2.getName());
     }
    return -1;
   }
}

public class TreeMapTest {
  public static void main(String[] args) {
     Map<Student,String> treeMap = new TreeMap<>(new StudentComparator());
  Student s1 = new Student("oldlu",18);
  Student s2 = new Student("admin",22);
  Student s3 = new Student("sxt",22);
  treeMap.put(s1,"oldlu");
  treeMap.put(s2,"admin");
  treeMap.put(s3,"sxt");
  Set<Student> keys1 = treeMap.keySet();
  for(Student key :keys1){
    System.out.println(key+" ---- "+treeMap.get(key));
    }
   }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值