Map双列集合

Map集合

一概述

1.Collection和Map集合的区别: Collection 中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。 Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的 值。
2 注意事项:Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

二Map集合常用子类

  • HashMap:. 存储数据采用的哈希表结构,元素的存取顺序不能保证一致,由于要保证键的唯一、不重复,需 要重写键的hashCode()方法、equals()方法
  • LinkedHashMap:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链 表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的 hashCode()方法、equals()方法。

三Map集合常用方法

  • public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中
  • public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的 值
  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值
  • public Set keySet() : 获取Map集合中所有的键,存储到Set集合中
  • public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
  • 方法的演示
public class MapDemo {
 public static void main(String[] args) { 
 //创建 map对象
  HashMap<String, String> map = new HashMap<String, String>(); 
  //添加元素到集合
   map.put("黄晓明", "杨颖");
    map.put("文章", "马伊琍");
     map.put("邓超", "孙俪"); 
     System.out.println(map); 
     //String remove(String key) 
     System.out.println(map.remove("邓超"));
      System.out.println(map); 
      // 想要查看 黄晓明的媳妇 是谁
       System.out.println(map.get("黄晓明")); 
       System.out.println(map.get("邓超")); } }

注:使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到 集合中; 若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的 值,替换成指定的新值

四Map集合遍历方式

1:Map集合遍历键找值方式

  1. 根据键,获取键所对应的值。运用方法: get(K key)
  2. 方法的演示
public class MapDemo01 {
 public static void main(String[] args) {
  //创建Map集合对象 
  HashMap<String, String> map = new HashMap<String,String>();
   //添加元素到集合 map.put("胡歌", "霍建华");
    map.put("郭德纲", "于谦"); 
    map.put("薛之谦", "大张伟"); 
    //获取所有的键 获取键集
    Set<String> keys = map.keySet();
     // 遍历键集 得到 每一个键
      for (String key : keys) { 
      //key 就是键 
      //获取对应值 
      String value = map.get(key);
       System.out.println(key+"的CP是:"+value); 
       } 
    } 
 }
  1. 图解
    在这里插入图片描述

2:运用Entry键值对对象遍历集合

  1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示: entrySet() 。
  2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
    1. 通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示: getkey() getValue()
  3. 代码演示
public class MapDemo02 {
 public static void main(String[] args) {
  // 创建Map集合对象
   HashMap<String, String> map = new HashMap<String,String>(); 
   // 添加元素到集合
    map.put("胡歌", "霍建华");
    map.put("郭德纲", "于谦");
    map.put("薛之谦", "大张伟");
    // 获取 所有的 entry对象 
    entrySet Set<Entry<String,String>> entrySet = map.entrySet();
     // 遍历得到每一个entry对象 
     for (Entry<String, String> entry : entrySet) {
      // 解析 
      String key = entry.getKey();
      String value = entry.getValue();
      System.out.println(key+"的CP是:"+value); 
     } 
   } 
}

注:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。

五HashMap存储自定义类型键值

  1. 练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到 map集合中。学生作为键, 家庭住址作为值。
  2. 注意,学生姓名相同并且年龄相同视为同一名学生。
  3. 代码演示
//编写学生类:
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; 
  return age == student.age && Objects.equals(name, student.name);
 }
   @Override
    public int hashCode() {
     return Objects.hash(name, age);
 } 
 }
//编写测试类
public class HashMapTest { public static void main(String[] args) { 
//1,创建Hashmap集合对象。
 Map<Student,String>map = new HashMap<Student,String>();
  //2,添加元素。
 map.put(newStudent("lisi",28), "上海");
 map.put(newStudent("wangwu",22), "北京");
 map.put(newStudent("zhaoliu",24), "成都");
 map.put(newStudent("zhouqi",25), "广州"); 
 map.put(newStudent("wangwu",22), "南京"); 
 //3,取出元素。键找值方式 
 Set<Student>keySet = map.keySet();
  for(Student key: keySet){
   Stringvalue = map.get(key); 
   System.out.println(key.toString()+"....."+value);
    } 
   } 
 }

注:当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的 hashCode和equals方法如果要保证map中存放的key和取出的顺序一致可以使用java.util.LinkedHashMap 集合来存放

六 LinkedHashMap

  1. 如果要保证map中存放的key和取出的顺序一致,可以使用 java.util.LinkedHashMap 集合来存放。
  2. 代码演示
public class LinkedHashMapDemo { 
public static void main(String[] args) { 
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
 map.put("邓超", "孙俪"); 
 map.put("李晨", "范冰冰");
  map.put("刘德华", "朱丽倩");
  Set<Entry<String, String>> entrySet = map.entrySet(); 
 for (Entry<String, String> entry : entrySet) {
  System.out.println(entry.getKey() + " " + entry.getValue()); 
   } 
  } 
 }

3结果;
在这里插入图片描述

七 JDK9对集合添加的优化

  1. Java 9,添加了几种集合工厂方法,更方便创建少量元素的集合、map实例。新的List、Set、Map的静态工厂方法可 以更方便地创建集合的不可变实例。
  2. 代码举例
public class HelloJDK9 {
 public static void main(String[] args) {
  Set<String> str1=Set.of("a","b","c");
   //str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合 
   System.out.println(str1);
    Map<String,Integer> str2=Map.of("a",1,"b",2);    
    System.out.println(str2);
    List<String> str3=List.of("a","b");
    System.out.println(str3);
    } 
  }

注意: 1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如 HashSet,ArrayList等待;
2:返回的集合是不可变的;

八 Debug追踪

  1. 在有效代码行,点击行号右边的空白区域,设置断点,程序执行到断点将停止,我们可以手动来运行程序
  2. 运行的时候点击右键,然后点击Debug运行模式
  3. 程序停止在断点上不再执行,而IDEA最下方打开了Debug调试窗口
  4. Debug调试窗口介绍
    在这里插入图片描述
  5. 如果不想继续debug,那么可以使用快捷键F9,程序正常执行到结束,程序结果在控制台显示
### 关于双列集合的数据结构、使用方法及其实现原理 #### 数据结构概述 双列集合是一种基于键值对(key-value pair)存储数据的集合类型。它在 Java 中主要由 `Map` 接口及其具体实现类构成,例如 `HashMap`、`TreeMap` 和 `LinkedHashMap` 等[^1]。这些实现类提供了不同的功能和性能特点。 - **键值对存储**:双列集合的核心特点是通过键来定位其对应的值。每个键只能映射到一个值,而多个键可以共享同一个值[^2]。 - **无序性与有序性**:大多数双列集合(如 `HashMap`)不保证元素的迭代顺序。然而,某些实现类(如 `TreeMap` 和 `LinkedHashMap`)则提供特定的排序或插入顺序保障[^3]。 --- #### 使用方法详解 以下是双列集合的主要操作方式: 1. **创建实例** 创建一个双列集合可以通过指定具体的实现类完成。例如: ```java Map<String, Integer> map = new HashMap<>(); ``` 2. **添加键值对** 使用 `put()` 方法将键值对插入集合中。如果键已存在,则会覆盖原有的值。 ```java map.put("Alice", 25); map.put("Bob", 30); ``` 3. **获取值** 利用 `get()` 方法通过键检索对应的值。如果键不存在,则返回 `null`。 ```java int ageOfAlice = map.get("Alice"); // 返回 25 ``` 4. **删除键值对** 调用 `remove()` 方法移除指定键的条目。 ```java map.remove("Bob"); ``` 5. **判断是否存在某个键或值** - 检查键的存在性:`containsKey()` - 检查值的存在性:`containsValue()` ```java boolean hasAlice = map.containsKey("Alice"); // true boolean hasAge30 = map.containsValue(30); // false ``` 6. **遍历集合** 遍历双列集合有多种方式,常见的包括: - 遍历键集 (`keySet`): ```java for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); } ``` - 遍历条目集 (`entrySet`): ```java for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } ``` 7. **清空集合** 使用 `clear()` 方法清除所有键值对。 ```java map.clear(); ``` --- #### 实现原理分析 1. **哈希表机制(以 `HashMap` 为例)** - `HashMap` 基于哈希表实现,内部维护了一个数组用于存储桶(bucket),每个桶可能是一个链表或红黑树[^4]。 - 当调用 `put()` 插入键值对时,计算键的哈希码并将其映射到相应的桶位置。如果发生冲突(两个键具有相同的哈希码),则通过链地址法解决冲突。 - 如果链表长度超过阈值(默认为8),该链表会被转换为红黑树以提高查询效率。 2. **平衡二叉树(以 `TreeMap` 为例)** - `TreeMap` 基于红黑树实现,能够保持按键的自然顺序或自定义比较器规定的顺序排列。 - 所有的插入、删除和查找操作的时间复杂度均为 O(log n),因为每次调整都会重新平衡树结构。 3. **链接列表(以 `LinkedHashMap` 为例)** - `LinkedHashMap` 继承自 `HashMap` 并额外维护了一条双向链表,记录了键值对的插入顺序。 - 这种设计使其既具备高效访问能力又保留了迭代顺序。 --- #### 总结 双列集合是 Java 编程中非常重要的工具之一,适用于需要快速按键查找值的场景。理解其基本特性和底层实现有助于开发者更合理地选择合适的实现类,并优化程序性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值