JAVA核心技术I---JAVA基础知识(映射Map)
一:映射Map分类
二:Hashtable(同步,慢,数据量小)
–K-V对,K和V都不允许为null –同步,多线程安全 –无序的 –适合小数据量 –主要方法:clear, contains/containsValue, containsKey, get, put,remove, size
(一)基本使用方法
Hashtable<Integer,String> ht=new Hashtable<Integer,String>(); //ht.put(1, null); //编译不报错 运行时报错 //ht.put(null, "das"); ht.put(1000, "adad"); ht.put(200, "adsdad"); ht.put(1, "adadge"); //进行判断是否含有数据 System.out.println(ht.contains("adad")); System.out.println(ht.containsValue("adad")); //contains和containsValue一样 System.out.println(ht.containsKey(1)); //进行数据获取 System.out.println(ht.get(1)); //进行更新 ht.put(1, "666"); //按照键,更新值 //进行移除 System.out.println(ht.containsKey(200)); ht.remove(200); System.out.println(ht.containsKey(200)); //获取大小 System.out.println(ht.size());
true true true adadge true false 2
(二)遍历方法
public static void traverseByEntry(Hashtable<Integer,String> ht){ long startTime = System.nanoTime(); System.out.println("=======Entry迭代器遍历======="); Integer key; String value; Iterator<Entry<Integer,String>> iter=ht.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> ent= iter.next(); key = ent.getKey(); value=ent.getValue(); System.out.println(key+":"+value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); }
public static void traverseByKeySet(Hashtable<Integer,String> ht){ long startTime = System.nanoTime(); System.out.println("=======KeySet迭代器遍历======="); Integer key; String value; Iterator<Integer> iter=ht.keySet().iterator(); while(iter.hasNext()) { key = iter.next(); value=ht.get(key); System.out.println(key+":"+value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); }
//Enumeration只在Hashtable中用到了,后面废弃不用 public static void traverseByKeyEnumeration(Hashtable<Integer,String> ht){ long startTime = System.nanoTime(); System.out.println("=======KeyEnumeration迭代器遍历======="); Integer key; String value; Enumeration<Integer> keys=ht.keys(); //一次性获取所有的key值, while(keys.hasMoreElements()) { key = keys.nextElement(); // 获取value value = ht.get(key); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); }
(三)性能测试:数据量越大,差距越小
for(int i=0;i<10000;i++) { ht.put(i, "aaa"); } //进行遍历 traverseByEntry(ht); traverseByKeySet(ht); traverseByKeyEnumeration(ht);
=======Entry迭代器遍历======= 13470233纳秒 =======KeySet迭代器遍历======= 8841551纳秒 =======KeyEnumeration迭代器遍历======= 4933705纳秒
三:HashMap(不支持同步,快,数据量大)
–K-V对,K和V都允许为nul –不同步,多线程不安全 Map m = Collections.synchronizedMap(new HashMap(...)); –无序的 –主要方法:clear, containsValue, containsKey, get, put,remove, size
(一)基本使用方法一致

HashMap<Integer,String> hm =new HashMap<Integer,String>(); hm.put(1, null); hm.put(null, "abc"); hm.put(1000, "aaa"); hm.put(2, "bbb"); hm.put(30000, "ccc"); System.out.println(hm.containsValue("aaa")); System.out.println(hm.containsKey(30000)); System.out.println(hm.get(30000)); hm.put(30000, "ddd"); //更新覆盖ccc System.out.println(hm.get(30000)); hm.remove(2); System.out.println("size: " + hm.size()); hm.clear(); System.out.println("size: " + hm.size());
(二)遍历方法除了没有Enumeration,其他一致

public static void traverseByEntry(HashMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============Entry迭代器遍历=============="); Integer key; String value; Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // 获取key key = entry.getKey(); // 获取value value = entry.getValue(); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); }

public static void traverseByKeySet(HashMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============KeySet迭代器遍历=============="); Integer key; String value; Iterator<Integer> iter = ht.keySet().iterator(); while(iter.hasNext()) { key = iter.next(); // 获取value value = ht.get(key); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); }
四:Properties (同步,文件形式,数据量小)
–继承于Hashtable –可以将K-V对保存在文件 –适用于数据量少的配置文件 –继承自Hashtable的方法:clear, contains/containsValue, containsKey, get, put,remove, size –从文件加载的load方法, 写入到文件中的store方法 –获取属性 getProperty ,设置属性setProperty
(一)使用方法
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Properties; //关于Properties类常用的操作 public class PropertiesTest { //根据Key读取Value public static String GetValueByKey(String filePath, String key) { Properties pps = new Properties(); try { InputStream in = new BufferedInputStream (new FileInputStream(filePath)); pps.load(in); //所有的K-V对都加载了 String value = pps.getProperty(key); //System.out.println(key + " = " + value); return value; }catch (IOException e) { e.printStackTrace(); return null; } } //读取Properties的全部信息 public static void GetAllProperties(String filePath) throws IOException { Properties pps = new Properties(); InputStream in = new BufferedInputStream(new FileInputStream(filePath)); pps.load(in); //所有的K-V对都加载了 Enumeration en = pps.propertyNames(); //得到配置文件的名字 while(en.hasMoreElements()) { String strKey = (String) en.nextElement(); String strValue = pps.getProperty(strKey); //System.out.println(strKey + "=" + strValue); } } //写入Properties信息 public static void WriteProperties (String filePath, String pKey, String pValue) throws IOException { File file = new File(filePath); if(!file.exists()) { file.createNewFile(); } Properties pps = new Properties(); InputStream in = new FileInputStream(filePath); //从输入流中读取属性列表(键和元素对) pps.load(in); //先加载原来的文件键值对,在其基础上进行设置,再写入 //调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。 //强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。 OutputStream out = new FileOutputStream(filePath); pps.setProperty(pKey, pValue); //以适合使用 load 方法加载到 Properties 表中的格式, //将此 Properties 表中的属性列表(键和元素对)写入输出流 pps.store(out, "Update " + pKey + " name"); out.close(); } public static void main(String [] args) throws IOException{ System.out.println("写入Test.properties================"); WriteProperties("Test.properties","name", "12345"); System.out.println("加载Test.properties================"); GetAllProperties("Test.properties"); System.out.println("从Test.properties加载================"); String value = GetValueByKey("Test.properties", "name"); System.out.println("name is " + value); } }
五:LinkedHashMap和TreeMap
LinkedHashMap
–基于双向链表的维持插入顺序的HashMap
TreeMap
–基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出

import java.util.LinkedHashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class LinkedHashMapTest { public static void main(String[] args) { LinkedHashMap<Integer,String> hm =new LinkedHashMap<Integer,String>(); hm.put(1, null); hm.put(null, "abc"); hm.put(1000, "aaa"); hm.put(2, "bbb"); hm.put(30000, "ccc"); System.out.println(hm.containsValue("aaa")); System.out.println(hm.containsKey(30000)); System.out.println(hm.get(30000)); hm.put(30000, "ddd"); //更新覆盖ccc System.out.println(hm.get(30000)); hm.remove(2); System.out.println("size: " + hm.size()); //hm.clear(); //System.out.println("size: " + hm.size()); System.out.println("遍历开始=================="); Integer key; String value; Iterator<Entry<Integer, String>> iter = hm.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // 获取key key = entry.getKey(); // 获取value value = entry.getValue(); System.out.println("Key:" + key + ", Value:" + value); } System.out.println("遍历结束=================="); LinkedHashMap<Integer,String> hm2 =new LinkedHashMap<Integer,String>(); for(int i=0;i<100000;i++) { hm2.put(i, "aaa"); } traverseByEntry(hm2); traverseByKeySet(hm2); } public static void traverseByEntry(LinkedHashMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============Entry迭代器遍历=============="); Integer key; String value; Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // 获取key key = entry.getKey(); // 获取value value = entry.getValue(); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); } public static void traverseByKeySet(LinkedHashMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============KeySet迭代器遍历=============="); Integer key; String value; Iterator<Integer> iter = ht.keySet().iterator(); while(iter.hasNext()) { key = iter.next(); // 获取value value = ht.get(key); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); } }

import java.util.TreeMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class TreeMapTest { public static void main(String[] args) { TreeMap<Integer,String> hm =new TreeMap<Integer,String>(); hm.put(1, null); //hm.put(null, "abc"); 编译没错,运行报空指针异常 hm.put(1000, "aaa"); hm.put(2, "bbb"); hm.put(30000, "ccc"); System.out.println(hm.containsValue("aaa")); System.out.println(hm.containsKey(30000)); System.out.println(hm.get(30000)); hm.put(30000, "ddd"); //更新覆盖ccc System.out.println(hm.get(30000)); //hm.remove(2); System.out.println("size: " + hm.size()); //hm.clear(); //System.out.println("size: " + hm.size()); System.out.println("遍历开始=================="); Integer key; String value; Iterator<Entry<Integer, String>> iter = hm.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // 获取key key = entry.getKey(); // 获取value value = entry.getValue(); System.out.println("Key:" + key + ", Value:" + value); } System.out.println("遍历结束=================="); TreeMap<Integer,String> hm2 =new TreeMap<Integer,String>(); for(int i=0;i<100000;i++) { hm2.put(i, "aaa"); } traverseByEntry(hm2); traverseByKeySet(hm2); } public static void traverseByEntry(TreeMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============Entry迭代器遍历=============="); Integer key; String value; Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // 获取key key = entry.getKey(); // 获取value value = entry.getValue(); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); } public static void traverseByKeySet(TreeMap<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============KeySet迭代器遍历=============="); Integer key; String value; Iterator<Integer> iter = ht.keySet().iterator(); while(iter.hasNext()) { key = iter.next(); // 获取value value = ht.get(key); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "纳秒"); } }
六:总结
–HashMap是最常用的映射结构
–如需要排序,考虑LinkedHashMap和TreeMap
–如需要将K-V存储为文件,可采用Properties类