热门标签 | 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

推荐阅读
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
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社区 版权所有