【JavaSE】Java基础语法(三十):HashMap与TreeMap

简介: 1. HashMap1.1 HashMap集合概述和特点HashMap底层是哈希表结构的依赖hashCode方法和equals方法保证键的唯一如果键要存储的是自定义对象,需要重写hashCode和equals方法

1. HashMap

1.1 HashMap集合概述和特点

  • HashMap底层是哈希表结构的
  • 依赖hashCode方法和equals方法保证键的唯一
  • 如果键要存储的是自定义对象,需要重写hashCode和equals方法

1.2 HashMap集合应用案例

案例需求

  • 创建一个HashMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并
    遍历。
  • 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象

代码实现

public class Student {
  private String name;
  private int age;
  public Student() {
  }
  public Student(String name, int age) {
    this.name = name;
    this.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 HashMapDemo {
  public static void main(String[] args) {
    //创建HashMap集合对象
    HashMap<Student, String> hm = new HashMap<Student, String>();
    //创建学生对象
    Student s1 = new Student("刘亦菲", 30);
    Student s2 = new Student("宋祖儿", 35);
    Student s3 = new Student("林黛玉", 33);
    Student s4 = new Student("林黛玉", 33);
    //把学生添加到集合
    hm.put(s1, "西安");
    hm.put(s2, "武汉");
    hm.put(s3, "郑州");
    hm.put(s4, "北京");
    //遍历集合
    Set<Student> keySet = hm.keySet();
    for (Student key : keySet) {
      String value = hm.get(key);
      System.out.println(key.getName() + "," + key.getAge() + "," + value);
    }
  }
}

2. TreeMap

2.1 TreeMap集合概述和特点

  • TreeMap底层是红黑树结构
  • 依赖自然排序或者比较器排序,对键进行排序
  • 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器
    排序规则

2.2 TreeMap集合应用案例一

案例需求

  • 创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年
    龄进行排序并遍历
  • 要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序

代码实现

public class Student implements Comparable<Student>{
  private String name;
  private int age;
  public Student() {
  }
  public Student(String name, int age) {
    this.name = name;
    this.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 String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", age=" + age +
    '}';
  }
  @Override
  public int compareTo(Student o) {
    //按照年龄进行排序
    int result = o.getAge() - this.getAge();
    //次要条件,按照姓名排序。
    result = result == 0 ? o.getName().compareTo(this.getName()) :
    result;
    return result;
  }
}
public class Test1 {
  public static void main(String[] args) {
    // 创建TreeMap集合对象
    TreeMap<Student,String> tm = new TreeMap<>();
    // 创建学生对象
    Student s1 = new Student("xiaohei",23);
    Student s2 = new Student("dapang",22);
    Student s3 = new Student("xiaomei",22);
    // 将学生对象添加到TreeMap集合中
    tm.put(s1,"江苏");
    tm.put(s2,"北京");
    tm.put(s3,"天津");
    // 遍历TreeMap集合,打印每个学生的信息
    tm.forEach(
      (Student key, String value)->{
        System.out.println(key + "---" + value);
      }
    );
  }
}

2.3 TreeMap集合应用案例二

案例需求

  • 给定一个字符串,要求统计字符串中每个字符出现的次数。
  • 举例: 给定字符串是“aababcabcdabcde”,在控制台输出: “a(5)b(4)c(3)d(2)e(1)”

代码实现

public class Test2 {
  public static void main(String[] args) {
  // 给定字符串
  String s = "aababcabcdabcde";
  // 创建TreeMap集合对象,键是Character,值是Integer
  TreeMap<Character,Integer> tm = new TreeMap<>();
  //遍历字符串,得到每一个字符
  for (int i = 0; i < s.length(); i++) {
    //c依次表示字符串中的每一个字符
    char c = s.charAt(i);
    // 判断当前遍历到的字符是否在集合中出现过
    if(!tm.containsKey(c)){
      //表示当前字符是第一次出现。
      tm.put(c,1);
    }else{
      //存在,表示当前字符已经出现过了
      //先获取这个字符已经出现的次数
      Integer count = tm.get(c);
      //自增,表示这个字符又出现了依次
      count++;
      //将自增后的结果再次添加到集合中。
      tm.put(c,count);
    }
  }
  // a(5)b(4)c(3)d(2)e(1)
  //System.out.println(tm);
  tm.forEach(
    (Character key,Integer value)->{
      System.out.print(key + "(" + value + ")");
    }
    );
  }
}

3. 总结

HashMap和TreeMap都是常用的Java集合框架中的映射类型,实现了Java中Map接口,并且具有不同的特点和使用场景。

HashMap的特点:

根据键的hashCode值存储数据,因此具有很快的访问速度;

允许使用null作为键和值;

不保证元素的顺序,在遍历元素时无法按照任何顺序输出。


TreeMap的特点:


按照键排序存储数据,因此可以保证元素按照一定顺序输出,这种顺序可以通过key的自然顺序或者自定义排序器决定;

不允许使用null作为键,但可以使用null作为值。在具体使用时,需要根据数据的特点和需要进行选择。


如果需要快速的查找、插入、删除操作,并且对元素的顺序没有特别要求,那么就应该使用HashMap。


如果需要按照键排序并且对元素的顺序有明确要求,那么可以使用TreeMap。同时,在需要在多线程环境下进行操作时,可以使用ConcurrentHashMap来代替HashMap,以保证线程安全。

相关文章
|
6天前
|
Java
Java之HashMap详解
本文介绍了Java中HashMap的源码实现(基于JDK 1.8)。HashMap是基于哈希表的Map接口实现,允许空值和空键,不同步且线程不安全。文章详细解析了HashMap的数据结构、主要方法(如初始化、put、get、resize等)的实现,以及树化和反树化的机制。此外,还对比了JDK 7和JDK 8中HashMap的主要差异,并提供了使用HashMap时的一些注意事项。
Java之HashMap详解
|
21天前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
38 1
|
21天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
36 1
|
20天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
45 5
|
21天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
37 3
|
21天前
|
存储 缓存 安全
在Java的Map家族中,HashMap和TreeMap各具特色
【10月更文挑战第19天】在Java的Map家族中,HashMap和TreeMap各具特色。HashMap基于哈希表实现,提供O(1)时间复杂度的高效操作,适合性能要求高的场景;TreeMap基于红黑树,提供O(log n)时间复杂度的有序操作,适合需要排序和范围查询的场景。两者在不同需求下各有优势,选择时需根据具体应用场景权衡。
26 2
|
21天前
|
存储 安全 Java
Java Map新玩法:深入探讨HashMap和TreeMap的高级特性
【10月更文挑战第19天】Java Map新玩法:深入探讨HashMap和TreeMap的高级特性,包括初始容量与加载因子的优化、高效的遍历方法、线程安全性处理以及TreeMap的自然排序、自定义排序、范围查询等功能,助你提升代码性能与灵活性。
23 2
|
21天前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文档重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android library开发建议以及在Kotlin和Java之间互相调用的方法。
18 1
|
21天前
|
安全 Java 编译器
Kotlin语法笔记(27) -Kotlin 与 Java 共存(二)
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。若需快速入门,建议查阅“简洁”系列教程。本文重点探讨Kotlin与Java共存的高级话题,包括属性访问、空安全、泛型处理、同步机制及SAM转换等,助你在项目中逐步引入Kotlin。
18 1
|
3月前
|
存储 安全 Java
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)
这篇文章是关于Java面试的第二天笔记,涵盖了HashMap与HashTable的区别、ConcurrentHashMap的实现原理、IOC容器的实现方法、字节码的概念和作用、Java类加载器的类型、双亲委派模型、Java异常体系、GC如何判断对象可回收、线程的生命周期及状态,以及sleep、wait、join、yield的区别等十道面试题。
一天十道Java面试题----第二天(HashMap和hashTable的区别--------》sleep、wait、join)