ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

技术问答-11 java中的集合(6)-Map

2021-04-13 20:53:29  阅读:169  来源: 互联网

标签:11 Map java String WeakHashMap 键值 key wmap


Map

一、Map简介

Map提供了一个更通用的元素存储方法。Map集合类用于存储元素对(成为键值对),其中每个键映射一个值。

二、Map 常用类

1. HashMap
最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap 最多允许一条记录的键为Null(多条会覆盖 其实不为Null 的其他key值也不能重复);允许多条记录的值为Null 。非同步的。
2. HashTable
与HashMap 类似 不同的是key和value的值不允许为null,它支持线程的同步,即任一时刻只有一个线程能写HashTable,这也导致了HashTable写入的时候比较慢!是很慢,新版本jdk不用他了 用ConcurrentHashMap代替
3.Proreties

import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.util.Iterator;import java.util.Properties;import java.util.Map.Entry;/**
 * 对属性文件操作的工具类
 * 获取,新增,修改
 * 注意:	以下方法读取属性文件会缓存问题,在修改属性文件时,不起作用,
 * InputStream in = PropertiesUtils.class.getResourceAsStream("/config.properties");
 * 解决办法:
 * String savePath = PropertiesUtils.class.getResource("/config.properties").getPath();
 * @author sdj
 */public class PropertiesUtils {/**
	 * 获取属性文件的数据 根据key获取值
	 * @param fileName 文件名 (注意:加载的是src下的文件,如果在某个包下.请把包名加上)
	 * @param key
	 * @return
	 */public static String findPropertiesKey(String key) {try {
			Properties prop = getProperties();return prop.getProperty(key);} catch (Exception e) {return "";}}public static void main(String[] args) {
		Properties prop = new Properties();
		InputStream in = PropertiesUtils.class.getResourceAsStream("/config.properties");try {
			prop.load(in);
			Iterator<Entry<Object, Object>> itr = prop.entrySet().iterator();while (itr.hasNext()) {
				Entry<Object, Object> e = (Entry<Object, Object>) itr.next();
				System.err.println((e.getKey().toString() + "" + e.getValue().toString()));}} catch (Exception e) {}}/**
	 * 返回 Properties
	 * @param fileName 文件名 (注意:加载的是src下的文件,如果在某个包下.请把包名加上)
	 * @param 
	 * @return
	 */public static Properties getProperties(){
		Properties prop = new Properties();
		String savePath = PropertiesUtils.class.getResource("/config.properties").getPath();//以下方法读取属性文件会缓存问题//		InputStream in = PropertiesUtils.class//				.getResourceAsStream("/config.properties");try {
			InputStream in =new BufferedInputStream(new FileInputStream(savePath));  
			prop.load(in);} catch (Exception e) {return null;}return prop;}/**
	 * 写入properties信息
	 * 
	 * @param key
	 *            名称
	 * @param value
	 *            值
	 */public static void modifyProperties(String key, String value) {try {// 从输入流中读取属性列表(键和元素对)
			Properties prop = getProperties();
			prop.setProperty(key, value);
			String path = PropertiesUtils.class.getResource("/config.properties").getPath();
			FileOutputStream outputFile = new FileOutputStream(path);
			prop.store(outputFile, "modify");
			outputFile.close();
			outputFile.flush();} catch (Exception e) {}}}

4.LinkedHashMap
保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候比HashMap慢,key value 均允许为null ,非同步的
5.IdentituHashMap
他与HashMap唯一的不同之处是,他的key值允许重复,但是key必须是两个不同的对象,也就是说k1和k2 当 k1 == k2 时,IdentityHashMap 认为两个Key相等,而HashMap只有在k1.equals(k20) == true 时 就会认为两个key相等
6.TreeMap

package along;import java.util.HashMap;import java.util.IdentityHashMap;public class Test2 {
   public static void main(String[] args) {
   	IdentityHashMap<String,String> im = new IdentityHashMap<String,String>();
   	HashMap<String,String> hm = new HashMap<String,String>();
   	String key1 = new String("ceshi");
   	String key2 = new String("ceshi");
   	System.out.println(key1 == key2);//false
   	System.out.println(key1.equals(key2));//true
   	
   	im.put(key1, "测试");
   	im.put(key2, "测试2");
   	
   	hm.put(key1, "测试");
   	hm.put(key2, "测试2");
   	System.out.println(im);//{ceshi=测试, ceshi=测试2}
   	System.out.println(hm);//{ceshi=测试2}
   }}

7.WeakHashMap
- 和HashMap一样,也是一个散列表,它存储的内容也是键值对,而且键和值都可以是null
- 不是同步的 但是Java提供同步方式

     Collections.synchronizedMap(new WeakHashMap<>());

  • 不过WeakHashMap的键是弱键,

  • 在WebkHashMap中,当某个键不再正常使用时,会被从WeakHashMap中被自动移除。

  • 更精确的说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收,某个键被终止时,它对应的键值对也就从映射中移除了
    这个弱键的原理是通过WeakReference和ReferenceQueue实现的。WeakHashMap 的key是弱键,即是WeakReference类型的;ReferenceQueue是一个队列,它会保存被GC回收的弱键。

  • 弱键如何被自动从WeakHashMap中删除的步骤
    1)新建WeakHashMap 将键值对添加到WeakHashMap中
    实际上,WeakHashMap 是通过数组table保存Entry(键值对) ;每一个Entry实际上是一个单向链表,即Entry是键值对链表。

    2)当某个弱键不再被其它对象引用,并被GC回收时,在GC回收该弱键时,这个弱键也同时被添加到ReferenceQueue队列中。

    3)当下一次我们需要操作WeakHashMap时,会先同步table和queue,table中保存了全部的键值对,而queue中保存了被GC回收的键值对;同步他们就是删除table中被GC回收的键值对

package along;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.WeakHashMap;/**
*  WeakHashMap实例
*/public class Test2 {

   public static void main(String[] args) throws Exception {   // 初始化3个“弱键”  不被引用的时候就成了弱键(比如w1 = null;  w1就成了弱键)   String w1 = new String("one");   String w2 = new String("two");   String w3 = new String("three");   // 新建WeakHashMap   Map<String,String> wmap = new WeakHashMap<String,String>();   // 添加键值对   wmap.put(w1, "w1");   wmap.put(w2, "w2");   wmap.put(w3, "w3");   // 打印出wmap内容   System.out.printf("\n原始 wmap:%s\n",wmap );   // containsKey(Object key) :是否包含键key   System.out.printf("包含key => two : %s\n",wmap.containsKey("two"));   System.out.printf("包含key => five : %s\n",wmap.containsKey("five"));   // containsValue(Object value) :是否包含值value   System.out.printf("包含值  => w1 : %s\n",wmap.containsValue("w1"));   // remove(Object key) : 删除键key对应的键值对   wmap.remove("three");// wmap.remove(w3); 也一样   System.out.printf("删除three 的 wmap: %s\n",wmap );   // ---- 测试 WeakHashMap 的自动回收特性 ----
   
       // 将w1设置null。   // 这意味着“弱键”w1再没有被其它对象引用,调用gc时会回收WeakHashMap中与“w1”对应的键值对   w1 = null;   // 内存回收。这里,会回收WeakHashMap中与“w1”对应的键值对   System.gc();   // 遍历WeakHashMap   Iterator<Entry<String, String>> iter = wmap.entrySet().iterator();   while (iter.hasNext()) {   Map.Entry<String, String> en = iter.next();   System.out.printf("next : %s - %s\n",en.getKey(),en.getValue());   }   // 打印WeakHashMap three被删除了 one 被回收了      System.out.printf("gc 后的wmap :%s\n", wmap);
   
   }}

8.ConcurrentHashMap
推荐看一篇文章 很受用

  • ConcurrentHashMap支持并发操作也就是线程安全的
    整个ConcurrentHashMap 由一个个Segment组成,Segment代表“段”或“部分”的意思,很多地方都会将其描述为分段锁
  • 简单理解就是,ConcurrentHashMap是一个Segment数组,
  • Segment通过集成ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住一个Segment,这样只要保证每个Segment是线程安全的,也就实现了全局的线程安全。
  • 具体介绍以及jdk1.8对HashMap的升级 在上边推荐的文章中已经提到,去看那篇文章就行了 文章写得很好 ,但是这个很难理解 需要时间领悟。
三、Map 专用类

专用Map 通常我们不需要亲自创建这类map 而是通过某些其他类对其进行访问
java.util.jar.Attributes javax.print.attribute.standard.PrinterStateReasons
java.security.Provider java.awt.RenderingHints javax.swing.UIDefaults

四、一个帮助我们实现自己的Map类的抽象类

AbstractMap

到这里集合就写得差不多了,肯定有漏的,也不是那么深入,但是一点点的进步也叫进步。有一句话叫: 不积跬步,无以至千里;不积小流,无以成江海。

标签:11,Map,java,String,WeakHashMap,键值,key,wmap
来源: https://blog.51cto.com/u_12198094/2704029

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有