Map接口

1.Map接口

Map接口存储键值映射的数据

1.1HashMap

HashMap:无序,键和值可以为null,键不能重复,线程不安全
数据结构
hashMap数据结构
数据结构

HashMap数据结构

回顾我们之前学过的两种数据结构:

ArrayList基于数组的,因为有下标,所以查询、修改快,增删慢

LinkedList基于链表的,因为没有下标,所以查询、修改慢,增删快

以上两个数据结构是刚好互补的,如果能将两个数据结构结合在一起,完美~

这只是理想状态,实际情况不会这么完美,另外结合在一起比较浪费空间

HashMap就是将两种数据结构结合在了一起

JDK7 数组 + 单向链表

JDK8 数组 + 单向链表 + 红黑树

HashMap数据的存放过程:

HashMap中一个元素是一个Node(节点),一个节点包含四个部分:Key值,value值,根据key计算出来的hash值,下一个元素的引用next

当我们调用put方法往HashMap中存储数据,会先根据key的hash值找到当前元素应该存放在数组中的位置,

如果此位置没有元素,则直接存放,

如果此位置有元素,那么向下延伸为单向链表

如果链表的长度大于8并且元素的总个数超过64 那么单向链表转换为红黑树

在我们使用过程中,我们会删除元素,如果链表的长度小于6,将红黑树再次转换为链表

HashMap中两个重要的数值:

16 表示数组的长度为初始长度16

0.75 表示数组的使用率达到75% 就扩容 扩容两倍 resize() 方法

常用方法

package com.qfedu.test6;

import java.util.HashMap;

/**
 * 	Map接口
 * 	HashMap常用方法
 * @author WHD
 *
 */
public class Test1 {
	public static void main(String[] args) {
		HashMap<String,String> map = new HashMap<String,String>();
		map.put("CN", "中国");
		map.put("US", "美国");
		map.put("JP", "小日本");
		map.put("KR", "棒子");
		map.put("ID","阿三");
		
		System.out.println(map.size());
		
		System.out.println(map.remove("JP")); // 删除
		
		System.out.println(map.size()); // 长度
		
		map.put("CN", "中华人民共和国"); // 存放
		
		System.out.println(map.get("CN")); // 获取
		
		map.replace("US", "美国佬");
		
		System.out.println(map.get("US"));
		
		map.clear();
		
		System.out.println(	map.isEmpty());
		
		
	}
}

遍历

package com.qfedu.test7;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 	HashMap 遍历方式
 * 	1.获取所有的键
 * 	2.获取所有的值
 * 	3.获取所有的键的迭代器
 * 	4.获取所有的值的迭代器
 * 	5.获取所有的元素Entry数组 
 * 	6.获取所有的元素的迭代器
 * @author WHD
 *
 */
public class Test1 {
	public static void main(String[] args) {
		HashMap<String,String> map = new HashMap<String,String>();
		map.put("CN", "中国");
		map.put("US", "美国");
		map.put("JP", "小日本");
		map.put("KR", "棒子");
		map.put("ID","阿三");
		
		// 1.获取所有的键
		Set<String> keySet = map.keySet();
		for(String key : keySet) {
			System.out.println(key + "\t" +  map.get(key) );
		}
		System.out.println("=====================================");
		
		// 2. 获取所有的值
		Collection<String> values = map.values();
		for(String v : values) {
			System.out.println(v);
		}
		System.out.println("=====================================");
		
		// 3.获取键的迭代器
		Iterator<String> iterator = map.keySet().iterator();
		while(iterator.hasNext()) {
			String key = iterator.next();
			System.out.println(key + "\t" + map.get(key));
		}
		System.out.println("=====================================");
		// 4.获取所有的值的迭代器
		Iterator<String> iterator2 = map.values().iterator();
		while(iterator2.hasNext()) {
			System.out.println(iterator2.next());
		}
		System.out.println("=====================================");
		// 5.获取所有的键值对组合 
		Set<Entry<String, String>> entrySet = map.entrySet();
		for(Entry<String,String> entry : entrySet) {
			System.out.println(entry.getKey() + entry.getValue());
		}
		System.out.println("=====================================");
		// 6.所有键值对组合的迭代器
		Iterator<Entry<String, String>> iterator3 = map.entrySet().iterator();
		while(iterator3.hasNext()) {
			Entry<String, String> next = iterator3.next();
			System.out.println(next.getKey() + next.getValue());
		}
		
	}
}

2.2Hashtable

Hashtable JDK1.0 提供与HashMap相同的API 并且不允许null作为键或者值 线程安全

初始长度为11 负载因子0.75 扩容 rehash() 两倍+1

HashMap与Hashtable的区别?

HashMap线程不安全 Hashtable线程安全

HashMap允许null键和值 Hashtable不允许

HashMapJDK1.2 Hashtable JDK1.0

package com.qfedu.test2;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 	Hashtable JDK1.0 提供与HashMap相同的API  并且不允许null作为键或者值  线程安全
 * 	初始长度为11 负载因子0.75 扩容 rehash() 两倍+1
 * @author WHD
 *
 */
public class TestHashtable {
	public static void main(String[] args) {
		Hashtable<Integer,String> table = new Hashtable<Integer,String>();
		table.put(1, "a");
		table.put(2, "b");
		table.put(3, "c");
		table.put(4, "d");
//		table.put(null, null);
		
		
		System.out.println(table.remove(1));
		System.out.println(table.size());
		
		table.replace(2, "hello");
		System.out.println(table.get(2));
		//table.clear();
		System.out.println(table.isEmpty());
		
		// 遍历方式与HashMap一致
		Set<Integer> keySet = table.keySet();
		for (Integer key : keySet) {
			System.out.println(table.get(key) + "\t" + key);
		}
		
		Collection<String> values = table.values();
		for (String v : values) {
			System.out.println(v);
		}
		
		Set<Entry<Integer, String>> entrySet = table.entrySet();
		for (Entry<Integer, String> entry : entrySet) {
			System.out.println(entry.getKey() + entry.getValue());
		}
		
	}
}

2.3LinkedHashMap

LinkedHashMap是基于双向链表的有序的Map集合,顺序为插入顺序

package com.qfedu.test3;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 	LinkedHashMap是有序的Map集合  顺序为插入顺序
 * @author WHD
 *
 */
public class TestLinkedHashMap {
	public static void main(String[] args) {
		LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
		map.put("a", "A");
		map.put("b", "B");
		map.put("c", "C");
		map.put("d", "D");
		
		System.out.println(map.remove("a"));
		
		map.replace("b", "hello");
		
		System.out.println(map.get("b"));
		
		System.out.println(map.size());
		
		// map.clear();
		
		System.out.println(map.isEmpty());
		// 遍历方式与之前Map集合一致
		
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + "---" + map.get(key));
		}
		
		
		Collection<String> values = map.values();
		for (String v : values) {
			System.out.println(v);
		}
		
		Set<Entry<String, String>> entrySet = map.entrySet();
		for (Entry<String, String> entry : entrySet) {
			System.out.println(entry.getKey() + "===" + entry.getValue());
		}
		
	}
}

2.3TreeMap

基于树的Map集合,有序是按照键的比较顺序
使用自定义的类型作为Map键,必须实现Comparable接口 重写compareTo方法
指定比较规则 否则运行报错 不能添加数据

package com.qfedu.test3;

import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

/**
 * 	基于树的Map集合  有序是按照键的比较顺序
 * 	使用自定义的类型作为TreeMap键 必须实现Comparable接口 重写compareTo方法 
 * 	指定比较规则 否则运行报错 不能添加数据 
 * @author WHD
 *
 */
public class TestTreeMap {
	public static void main(String[] args) {
		TreeMap<Integer,String> map = new TreeMap<Integer,String>();
		map.put(1, "abc");
		map.put(20, "hello");
		map.put(17, "hhh");
		map.put(5, "666");
		// 其他方法 增删改查 是否为空 与之前map集合一致 
		// 遍历方式与之前也一致
		Set<Integer> keySet = map.keySet();
		for (Integer key : keySet) {
			System.out.println(map.get(key) + "===" + key);
		}
		
		System.out.println("============================================");
		TreeMap<Student,String> map1 = new TreeMap<Student,String>();
		Student stu1 = new Student("赵四", 25);
		Student stu2 = new Student("广坤", 21);
		Student stu3 = new Student("大拿", 22);
		map1.put(stu1, "abc");
		map1.put(stu2, "abc");
		map1.put(stu3, "abc");
		
		Set<Entry<Student, String>> entrySet = map1.entrySet();
		for (Entry<Student, String> entry : entrySet) {
			System.out.println(entry.getKey());
			System.out.println(entry.getValue());
		}
		
	}
}
package com.qfedu.test3;

public class Student implements Comparable<Student>{
	private String name;
	private int 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;
	}
	public Student() {
	}
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Student stu) {
		if(this.getAge() > stu.getAge()) {
			return 1;
		}else if(this.getAge() < stu.getAge() ) {
			return -1;
		}
		return 0;
	}
	
}

2.4Properties

Properties类用于存放成对的字符串数据 实际开发中用于读取配置文件

所以此类不要使用从父类Hashtable继承来的put或者putAll方法

而应该使用setProperty()

package com.qfedu.test6;

import java.util.Properties;

/**
 * 	Properties类用于存放成对的字符串数据 实际开发中用于读取配置文件
 * 	所以此类不要使用从父类Hashtable继承来的put或者putAll方法
 * 	而应该使用setProperty() 
 * @author WHD
 *
 */
public class TestProperties {
	public static void main(String[] args) {
		System.out.println(System.getProperty("java.version"));
		System.getProperties().list(System.out);
		
		Properties p = new Properties();
//		p.put(1, "abc");
		p.setProperty("a", "A");
		p.setProperty("b", "B");
		
		System.out.println(p.get("a"));
		p.list(System.out);
		
		
		
		
	}
}
posted @ 2021-07-27 20:33  码丁XIA  阅读(85)  评论(0)    收藏  举报