热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java笔记十二.常用API-Hashtable类及其与HashMap、HashSet的区别

常用API-Hashtable类及其与HashMap、HashSet的区别转载请表明出处:http:blog.csdn.netu012637501(嵌入式_小J的天空)一、Hashtable&l
常用API-Hashtable类及其与HashMap、HashSet的区别
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)

一、Hashtable 1.概述     Hashtable是一种高级数据结构,实现了一个Key-Value映射的哈希表,用以快速检索数据。Hashtable不仅可以像Vector一样动态存储一系列的对象,而且对存储的每一个值对象(值)都安排与另一个键对象(关键字)相关联,非null对象都可以被使用作为键对象或者值对象。为了能够成功从hashtable中存储和读取对象元素,实现键对象的类必须实现hashCode方法和equals方法。 2.Hashtable类API(1)继承关系:java.lang.Object <----  java.util.Dictionary <----- java.util.Hashtable (2)构造方法
Hashtable()Constructs a new, empty hashtable with a default initial capacity (11) and load factor (0.75).
Hashtable(int initialCapacity)Constructs a new, empty hashtable with the specified initial capacity and default load factor (0.75).
Hashtable(int initialCapacity,
float loadFactor)
Constructs a new, empty hashtable with the specified initial capacity and the specified load factor.
Hashtable(Map extends K,?
extends V> t)
Constructs a new hashtable with the same mappings as the given Map.
(3)常用方法
boolean contains(Object value):检索hashtable表中是否有一些键映射到指定的值对象 boolean containsKey(Object key)检索hashtable表中是否包含指定的键对象 boolean containsValue(Object value):返回true,如果这个hashtable中一个或多个键映射到这个值 Enumeration elements():返回hashtable所有的元素到一个Emumeration对象 V get(Object key):返回键对应所映射的值对象,如果集合中不存在这样的映射则返回null boolean equals(Object o):比较指定的对象是否存在于Map集合中 int hashCode():计算哈希值 Enumeration keys():将hashtable所有的键值返回为一个Emumeration对象 V put(K key, V value) :将一个键值对映射添加到hashtable中  replace(K key, V value) :如果该映射存在,替代 Collection values() :返回存储结构中的所有值对象,返回类型为Collection类型 int size() :返回hashtable中键对象的个数 3.Hashtable类应用技巧 (1)如何向Hashtable对象中存储数据?     在Hashtable应用中使用Hashtable.put(Object key,Object value)方法存储数据;从Hashtable中检索数据,使用Hashtable.get(Object key)方法。值和关键字都可以是任何类型的非空的对象(?) 实例源码:设计一个存储数字的Hashtable,应英文数字作为关键字
Hashtable numbers=new Hashtable();
numbers.put("one",new Integer(1)); //向Hashtable数据结构中存储一个数据(为键值对)
numbers.put("two",new Integer(2));
numbers.put("three",new Integer(3));
Integer n=(Integer)numbers.get("two");//检索"two"关键字对应的数据,其中 numbers.get("two")返回Object类型值对象
if(n!=null)
{
System.in.println("two = "+n);
}

(2)为何需覆盖Object.hashCode方法和Object.equals方法?     由于作为key的对象通过计算其散列函数确定与之对应的value的位置,因此任何为key的对象都必须实现hasCode和equals方法。hasCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。  实例源码:编写一个类(MyKey.java)用于关键字,即这个类要实现equals和hashCode方法。  
class  MyKey
{
private String name;
private int age;
//1.构造函数:赋初值。其中this.name等价于MyKey的对象.name(调用私有变量并给其赋值)
public MyKey(String name,int age)
{
this.name=name;
this.age=age;
}
//2.重写toString方法:实现指定的功能-返回一个值为非空的String对象
public String toString()
{
return new String(name + ","+age);
}
//3.实现equals方法:当名字和年龄都一致时,可以判定为同一对象(Object obj)或者说要检索的键存在Hashtable存储结构中(如果存在返回true)
public boolean equals(Object obj)
{
MyKey mykey1=this;
MyKey mykey2=(MyKey)obj;
if(mykey1.name.equals(mykey2.name) && mykey2.age==mykey1.age) //其中obj为需要检索的对象
return true;
else
return false;
}
//4.哈希函数:确定Key对象与之对应Value的存储位置,相同对象的哈希值一定相同否者就会出现冲突
public int hashCode()
{
return name.hashCode()+age;
}
}

注释:当我们通过指定键对象检索Hashtable数据结构中是否包含该key-value键值对时,在重写equals方法中,需要定义两个MyKey对象, MyKey mykey1=this为Hashtable表中固有的键对象;MyKey mykey2=(MyKey)obj-由于Hashtable的get方法返回的是Object对象,所以我们需要将其转换为MyKey对象,然后再与前者进行变量比较然后再确定是否为同一目标。 4.实例源码:实现一个Hashtable数据结构,然后向其存储数据然后在进行检索。如果两个人名字和年龄都相同,我们就认为他们是同一个人。  HashtableTest.java(键对象的值---值对象的值)  
import java.util.*;
public class HashtableTest
{
public static void main(String[] args)
{
//1.构造一个Hashtable对象,即建立一个Hashtable并向其添加元素(key-value键值对)
Hashtable numbers=new Hashtable();
numbers.put(new MyKey("zhangsan",20),new Integer(1));//添加key-value键值对到结构中
numbers.put(new MyKey("lisi",18),new Integer(2));
numbers.put(new MyKey("wangwu",23),new Integer(3));
//2.使用Enumeration获取所有键对象并进行遍历
Enumeration e=numbers.keys(); //numbers.keys()返回hashtable中所有键对象元素
while(e.hasMoreElements()) //遍历每一元素的键对象
{
MyKey key=(MyKey)e.nextElement(); //e.nextElement返回的是一个Object对象
System.out.print(key.toString()+"="); //打印键对象的值,其中toString作用是打印指定的内容
System.out.println(numbers.get(key).toString());//打印Hashtable中键对象对应值对象的值,其中toSting的作用是将值对象的值转换为字符串输出
}
}
}

效果如下:
注释:在上面的这个程序中,我们定义了一个Hashtable的对象numbers,然后给他放入了3个MyKey类对象和对应的阿拉伯数字。最后,我们在假装不知道该对象里面的值的情况下。利用Emumeration接口的对象e将值和关键字一一对应地取出来
二、Properties类
1.概述  Properties是Hashtable的子类,与Hashtable的主要区别是Properties增加了将Hashtable对象中的关键字-值(key-value)对保存到文件(输入流)和从文件中读取关键字-值(key-value)对到Hashtable对象中的方法。Properties主要要用于应用程序的选项设置,即程序退出时将功能/设置值存储到文件,程序启动时将功能-设置值读到了内存,然后程序按新的设置运行。有一点需要注意的是,Properties数据结构的属性列表中的每个键及其对应的值是一个字符串,多线程安全。 2.Properties类API(1)继承关系:java.lang.Object <----  java.util.Dictionary <----- java.util.Hashtable <---java.util.Properties(2)构造方法
Properties() Creates an empty property list with no default values.
Properties(Properties defaults) Creates an empty property list with the specified defaults.注释:defaults-属性列表包含一些对应于任何键值的默认值,这些键值不存在于属性列表中
(3)常用方法
String getProperty(String key) :检索该属性列表中属性的指定键对象 Object setProperty(String key, String value) :相当与调用Hashtable的put方法,即向属性数据结构中添加键值对 void load(InputStream inStream) :从输入字节流读取属性列表(一系列键值对)     void load(Reader reader) 、void loadFromXML(InputStream in) 类似 void store(OutputStream out, String comments) :将Properties表中的属性列表(一系列键值对)到文件流     void store(Writer writer, String comments) 、void storeToXML(OutputStream os, String comment) 类似
  • Methods inherited from class java.util.Hashtable

    clear, clone, compute, computeIfAbsent, computeIfPresent, contains, containsKey, containsValue, elements, entrySet, equals, forEach, get,getOrDefault, hashCode, isEmpty, keys, keySet, merge, put, putAll, putIfAbsent, rehash, remove, remove, replace, replace, replaceAll, size,toString, values
  • Methods inherited from class java.lang.Object

    finalize, getClass, notify, notifyAll, wait, wait, wait
3.Properties类应用技巧
(1)程序选项属性的设置与读取、存储      如果用到Properties类的store方法进行存储每个属性的关键字和值都必须是字符串类型的,所以上面的程序没有用从父类Hashtable继承到的put、get方法进行属性的设置与读取,而是直接用了Properties类的setProperty、getProperty方法进行属性的设置与读取实现从文件读取设置属性、存储设置属性到文件中,有三种情况: a. load(Reader) / store(Writer, String):一般情况 b.load(InputStream) / store(OutputStream, String):当字符编码为 ISO 8859-1 c. loadFromXML(InputStream) and storeToXML(OutputStream, String, String):字符编码为UTF-8/UTF-16,文件类型为XML (2)实例源码     编写一个程序,当程序每次启动时都去读取一个记录文件,直接读取文件中所记录的运行次数并加1后,有重新将新的运行次数存回文件。
import java.util.*;
import java.io.*;
class PropertiesTest {
public static void main(String[] args)
{
Properties settings=new Properties();
//1.加载一个文件流,如果该文件不存在则表示打开的次数count=0
try
{
settings.load(new FileInputStream("C:\\count.txt"));//从文件中读取属性列表(为一系列键值对)到Properties结构中
}
catch(Exception e)
{
settings.setProperty("Count", new Integer(0).toString());//向Properties结构中存储键值对key-value
}
//2.次数累加并将其保存到count.txt文件中
int c=Integer.parseInt(settings.getProperty("Count"))+1;//获取键对象对应值对象的内容,并累加1(程序被打开一次)
System.out.println("这是本程序第"+c+"次被使用");
settings.put("Count", new Integer(c).toString()); //再次向Properties结构存储新的键值对
try
{
settings.store(new FileOutputStream("C:\\count.txt"), "This Program is used:");/*将Properties所有属性列表(所有键值对)保存到文件中*/
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}

效果演示:



总结一:HashMap与HashTable的区别?
        HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例,具体区别如下:1.Hashtable是基于Dictionary类的,而HashMap是基于Map接口的一个实现 2.Hashtable里默认的方法是同步的,而HashMap则是非同步的,因此Hashtable是多线程安全的,HashMap未经同步所以在多线程诚和要动手同步,使用以下语句对HashMap进行同步操作。                            Map m = Collections.synchronizedMap(new HashMap(...));3.HashMap可以将空值作为一个表的条目的key或者value,HashMap中由于键不能重复,因此只有一条记录的Key可以是空值,而value可以有多个为空,但HashTable不允许null值(键与值均不行4.内存初始大小不同,HashTable初始大小是11,而HashMap初始大小是16 5.内存扩容时采取的方式也不同,Hashtable采用的是2*old+1,而HashMap是2*old。 6.哈希值的计算方法不同,Hashtable直接使用的是对象的hashCode,而HashMap则是在对象的hashCode的基础上还进行了一些变化nt hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;而HashMap重新计算hash值,而且用与代替求模:int hash = hash(k);int i = indexFor(hash, table.length);static int hash(Object x) {  h ^= (h >>> 20) ^ (h >>> 12);     return h ^ (h >>> 7) ^ (h >>> 4);}static int indexFor(int h, int length) {  return h & (length-1);}7.HashTable使用Enumeration进行遍历,HashMap使用Iterator进行遍历
HashTable的遍历: Hashtable ht=new Hashtable();         ht.put("1", "111");         ht.put("3","333");         ht.put("2", "222");         Enumeration en=ht.keys();         while(en.hasMoreElements())        {
            Object key=en.nextElement();             Object value=ht.get(key);             System.out.println("key="+key+",value="+value);         }  
总结二:HashMap与HashSet的区别?

1. HashMap可以看作三个视图:Key的Set(不可重复),value的Collection(可重复且无序),Entry(链表)的Set,HashMap为散列映射,它是基于hash table的一个实现,它可在常量时间内安插元素,或找出一组key-value    HashSet为散列集,其底层采用的是HashMap进行实现的,但是没有key-value(即它不需要Key和Value两个值),只有HashMap的key-set的视图,HashSet不容许重复的对象。        public HashSet() {  
                        map = new HashMap<E,Object>();  
                 }  
2. 调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该行的key就是向HashSet增加的哪个对象,该行的value就是一个Object类型的常量
private static final Object PRESENT = new Object();   public boolean add(E e) {       return map.put(e, PRESENT)==null;       }   public boolean remove(Object o) {       return map.remove(o)==PRESENT;       } 

参考:http://docs.oracle.com/javase/8/docs/api/index.htmlhttp://blog.csdn.net/zwjlpeng/article/details/9746425http://blog.csdn.net/wl_ldy/article/details/5941770

推荐阅读
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 图解HashMap
    什么是HashMap,文章内HashMap源码主要来自Android7.0HashMap是开发中常用的一个类,那么他究竟是什么呢?HashMap是一个存储key-value的集合, ... [详细]
  • HashMap及HashTable源码解析HashMap在java和Android经常使用到,之前学过数据结构,理解了它的原理,却很 ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 我找到了这篇有关在Typescript中实现哈希图的帖子,除了从哈希图中删除某些内容 ... [详细]
  • 手写HashMap,快手面试官直呼内行
    手写HashMap,快手面试官直呼内行-手写HashMap?这么狠,面试都卷到这种程度了?第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章:这……我当 ... [详细]
  • 在Java中有多种遍历HashMap的方法,注意Java中所有的Map类型都实现了共有的Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,Linked ... [详细]
  • hashmap线程不安全允许有null的键和值效率高一点、方法不是Synchronize的要提供外同步有containsvalue和containsKey方法HashMap是Java1 ... [详细]
  • 源码阅读之HashMap(JDK8)
    概述HashMap根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。HashMap最多只允许一条记录的键为null,允许多条记 ... [详细]
  • 一、HashMap1.HashMap概述:HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是 ... [详细]
  • HashMap和Hashtable的区别主要的区别有三点:线程安全性,同步(synchronization),以及速度。(两者都是无序排放)HashMap几乎可以等价于Hashtable,除了Hash ... [详细]
author-avatar
手机用户2502872003
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有