词典的实现(3)--使用JAVA类库ArrayList实现Map数据结构
1,在词典的实现(2)-借助顺序表(数组)实现词典文章中使用了自定义的数组代替ArrayList,并实现了Map数据结构的基本功能。而借助JAVA类库ArrayList类的一些方法可以更加容易地实现Map。
2,实现思路如下
ArrayListDictionary.java 中定义了一个ArrayList的对象,该ArrayList对象用来存储Entry类的对象,而Entry类封装了(key,value)。这样,利用ArrayList类的一些方法来间接地操作(key,value),从而实现各种词典的操作。
ArrayListDictionary.java 中部分代码解释如下:
public ArrayListDictionary(){
listDictionary = new ArrayList<Entry>();
}
在构造方法中初始化ArrayList对象。这样,每生成一个词典对象,就会有一个ArrayList对象。因为,每个词典对象都需要一个ArrayList对象来存储词典中的元素。
private class Entry{
K key;
V value;
私有内部类Entry用来封装(key,value)对,key 只有get方法没有set方法。因为对于词典而言,key是不能更改的。而value既有get方法又有set方法。
private class KeyIterator<S> implements Iterator<K>{
Iterator<Entry> it = null;
public KeyIterator(){
it = listDictionary.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public K next() {
return (K) it.next().getKey();
}
@Override
public void remove() {
throw new UnsupportedOperationException("can not remove a entry in iterator.unsupported");
}
}
私有内部类KeyIterator用来实现词典中键的迭代器。该迭代器的实现基于遍历Entry的迭代器,由于ArrayList存储Entry对象,因此可以借助ArrayList的iterator()方法很容易地得到遍历Entry的迭代器。在KeyIterator的构造方法中实例化遍历Entry对象的迭代器后,通过实现Iterator接口的三个方法来实现遍历词典的查找键的迭代器。
@Override
public Iterator<K> getKeyIterator() {
return new KeyIterator();
}
ArrayListDictionary.java的getKeyIterator()方法返回一个遍历词典查找键的迭代器的对象。这样,ArrayListDictionary的对象就可以调用该方法来得到该迭代器了。
private int locateIndex(K key){
int index = -1;
Iterator<Entry> it = listDictionary.iterator();
while(it.hasNext()){
Entry e = it.next();//先获得每一个Map元素
if(e.getKey().equals(key)){//依次与每一个Map元素的查找键比较
index = listDictionary.indexOf(e);//获得给定的key匹配的Map元素在Arraylist中的位置
break;
}
}
return index;
}
私有方法locateIndex(K key),用来查找某个查找键在ArrayList数组中的哪个位置。由于ArrayList数组中存储的是Entry对象,因此先要通过遍历Entry的迭代器获得Entry对象,然后通过Entry类的getKey()方法来获得Entry对象的key属性。index 返回 –1 表示查找键key(所代表的Entry对象)不在ArrayList中。
public V remove(K key) {
V result = null;
int index = locateIndex(key);
if(index == -1){//key 不存在于ArrayList中
result = null;
}
else{
result = listDictionary.get(index).getValue();
listDictionary.remove(index);
}
return result;
}
remove()用来删除词典中的元素。其他的一些方法的功能可以参考DictionaryInterface.java中声明的方法解释。
整个完整的ArrayListDictionary.java实现如下
package dictionary; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator; public class ArrayListDictionary<K,V> implements DictionaryInterface<K, V>,Serializable { private static final long serialVersionUID = 1L;
ArrayList<Entry> listDictionary = null; public ArrayListDictionary(){
listDictionary = new ArrayList<Entry>();
} private class Entry{
K key;
V value; private Entry(K key, V value){
this.key = key;
this.value = value;
} public K getKey() {
return key;
} public V getValue() {
return value;
} public void setValue(V value) {
this.value = value;
}
} private class KeyIterator<S> implements Iterator<K>{ Iterator<Entry> it = null;
public KeyIterator(){
it = listDictionary.iterator();
} @Override
public boolean hasNext() {
return it.hasNext();
} @Override
public K next() {
return (K) it.next().getKey();
} @Override
public void remove() {
throw new UnsupportedOperationException("can not remove a entry in iterator.unsupported"); }
} private class ValueIterator<V> implements Iterator<V>{ Iterator<Entry> it = null;
public ValueIterator(){
it = listDictionary.iterator();
} @Override
public boolean hasNext() {
return it.hasNext();
} @Override
public V next() {
return (V) it.next().getValue();
} @Override
public void remove() {
throw new UnsupportedOperationException();
}
} //返回指定的查找键所代表的元素在arraylist中的位置
private int locateIndex(K key){
int index = -1;
Iterator<Entry> it = listDictionary.iterator();
while(it.hasNext()){
Entry e = it.next();//先获得每一个Map元素
if(e.getKey().equals(key)){//依次与每一个Map元素的查找键比较
index = listDictionary.indexOf(e);//获得给定的key匹配的Map元素在Arraylist中的位置
break;
}
}
return index;
} @Override
public V add(K key, V value) {
V result = null;
int index = locateIndex(key);
if(index == -1){//key 不在ArrayList中
listDictionary.add(new Entry(key, value));
}
else{
//这里index不会为-1,所以 get(index)不会抛出IndexOutOfBoundsException
result = listDictionary.get(index).getValue();
listDictionary.get(index).setValue(value);//调用Entry内部类中的setValue方法更新Entry的Value
}
return result;
} @Override
public V remove(K key) {
V result = null;
int index = locateIndex(key);
if(index == -1){//key 不存在于ArrayList中
result = null;
}
else{
result = listDictionary.get(index).getValue();
listDictionary.remove(index);
}
return result;
} @Override
public V getValue(K key) {
V result = null;
int index = locateIndex(key);
try{
result = listDictionary.get(index).getValue();//当index=-1时,表示key不存在
}catch(IndexOutOfBoundsException e){//index = -1时抛出异常
result = null;
}
return result;
} @Override
public boolean contains(K key) {
boolean result = false;
Iterator<Entry> it = listDictionary.iterator();
while(it.hasNext()){
Entry e = it.next();
if(e.getKey().equals(key)){
result = true;
break;
}
}
return result;
} @Override
public Iterator<K> getKeyIterator() {
return new KeyIterator();
} @Override
public Iterator<V> getValueIterator() {
return new ValueIterator();
} @Override
public boolean isEmpty() {
return listDictionary.isEmpty();
} @Override
public boolean isFull() {
return false;
} @Override
public int getSize() {
return listDictionary.size();
} @Override
public void clear() {
listDictionary.clear();
}
}
在实现完词典后,以下写了个测试程序借且词典来统计单词的个数。思路如下:
文本文件word.txt中存放待统计的单词,词典客户端程序PrintWordsFrequency.java 提供word.txt,然后查看每个单词出现的次数。
词典表FrequencyCounterDictionary.java负责统计word.txt中的单词并将结果存储到Map词典中,并实现对词典的遍历(display())。
PrintWordsFrequency.java 代码如下:
package dictionary.common;
package dictionary.client; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner; import dictionary.common.FrequencyCounterDictionary; public class PrintWordsFrequency {
public static void main(String[] args) {
FrequencyCounterDictionary wordCounter = new FrequencyCounterDictionary();
String fileName = "word.txt";//存放单词的文本文件,统计其中的单词出现次数
try{
Scanner data = new Scanner(new File(fileName));
wordCounter.readFile(data);
}catch(FileNotFoundException e){
System.out.println("File not found: " + e.getMessage());
}catch(IOException e){
System.out.println("I/O error" + e.getMessage());
} wordCounter.display();
System.out.println("Bye");
}
}
FrequencyCounterDictionary.java代码如下:
package dictionary.common; import java.util.Iterator;
import java.util.Scanner; import dictionary.ArrayListDictionary;
import dictionary.DictionaryInterface; public class FrequencyCounterDictionary {
private DictionaryInterface<String, Integer> wordTable; public FrequencyCounterDictionary(){
wordTable = new ArrayListDictionary<String, Integer>();
} public void readFile(Scanner data){
data.useDelimiter("\\W+");
while(data.hasNext()){
String nextWord = data.next();//从Scanner打开的输入流中读取单词
nextWord.toLowerCase();
Integer frequency = wordTable.getValue(nextWord);//判断该单词在词典中已出现的次数 if(frequency == null){//单词从未出现过
wordTable.add(nextWord, new Integer(1));//将其出现次数置 1
}
else//单词已经在词典中
{
frequency++;//出现次数增 1
wordTable.add(nextWord, frequency);
}
}//end while
data.close();
} public void display(){
Iterator<String> keyIterator = wordTable.getKeyIterator();
Iterator<Integer> valueIterator = wordTable.getValueIterator();
while(keyIterator.hasNext()){
System.out.println(keyIterator.next() + " : " + valueIterator.next());
}
}
}
运行结果
文本文件内容如下:


词典的实现(3)--使用JAVA类库ArrayList实现Map数据结构的更多相关文章
- Java 的 ArrayList 的底层数据结构
1. 数据结构--ArrayList源码摘要 ublic class ArrayList<E> extends AbstractList<E> implements List& ...
- 介绍4款json的java类库 及 其性能测试
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...
- 使用Java类库POI生成简易的Excel报表
使用Java类库POI生成简易的Excel报表 1.需求 1.数据库生成报表需要转义其中字段的信息.比如 1,有效 2.无效等 2.日期格式的自数据需要转义其格式. 3.标题的格式和数据的格式需要分别 ...
- java类库 collection与collections (转)
http://www.cnblogs.com/dashi/p/3597937.html Java中Collection和Collections的区别 1.java.util.Collection 是一 ...
- 【thinking in java】ArrayList源码分析
简介 ArrayList底层是数组实现的,可以自增扩容的数组,此外它是非线程安全的,一般多用于单线程环境下(Vector是线程安全的,所以ArrayList 性能相对Vector 会好些) Array ...
- 学习使用Delphi for android 调用Java类库
http://blog.csdn.net/laorenshen/article/details/41148253 学习使用Delphi for android 调用Java类库 2014-11-15 ...
- 解决springmvc报No converter found for return value of type: class java.util.ArrayList问题
一.背景 最近闲来无事,想自己搭建一套Spring+SpringMVC+Mybatis+Mysql的环境(搭建步骤会在以后博客中给出),结果运行程序时,适用@ResponseBody注解进行返回Lis ...
- java 遍历arrayList的四种方法
package com.test; import java.util.ArrayList;import java.util.Iterator;import java.util.List; public ...
- 初涉java库--ArrayList
我的车就差一个轮子啦,造好轮子,我就飞上天与太阳肩并肩啦,想想都激动.什么你要自己造轮子,是不是傻,商店里不都是别人造好的吗,又好又方便,只需一点money,你没有money,那你只能做个安静的美男子 ...
随机推荐
- java中的随机数Random
java中一般有两种随机数,一个是Math中random()方法,一个是Random类. 一.Math.random() : 随即生成0<x<1的小数 实例:如何写,生成随机生成 ...
- [同事转帖] .net core的服务器模式和工作站模式
发现自己的服务器上面的进程占用越来越厉害 所以就跟同事讨论了一下 性能组同事 说已经发现 并且给了一个 网址 这里转帖记录一下 避免以后找不到. .NET Core是一个开源通用的开发框架,具有跨平台 ...
- ESXi安装时遇到不识别的硬件的处理
1. 部门新购置了一台inspur 四路 NF8480M4的服务器. 上架之后发现ESXi的标准安装盘无法安装. 找不到磁盘安装介质. 2. 处理办法, 找浪潮专家服务,报上序列号,要上相关的一些软件 ...
- SAP字体调节大小
登陆SAP 之后,菜单下面一行,最右边的那个彩色按钮(SAP GUI),点击“选项”-可视设计-字体设计-固定狂赌字体设计,点击:选择字体 即可.
- the project already contains a form or module named pcm001怎麼解決
the project already contains a form or module named pcm001怎麼解決 菜单Project -> Remove from project.. ...
- BZOJ4650 NOI2016优秀的拆分(后缀数组)
显然只要求出以每个位置开始的AA串数量就可以了,将其和反串同位置的结果乘一下,加起来就是答案.考虑对每种长度的字符串计数.若当前考虑的A串长度为x,我们每隔x个字符设一个关键点,求出相邻两关键点的后缀 ...
- git各种撤销提交
Git的几种状态 未修改 工作区 已修改 ↓ 工作区 已暂存 ↓ 暂存区 已提交 ↓ 本地仓库 已推送 ↓ 远程仓库 已修改 未暂存 已经修改了文件,还未进行git add 恢复方法 使用一下任意 ...
- mycat实现简单的mysql集群负载均衡
什么是mycat呢? 简单理解为一个MySQL中间件,它支持分流.基于心跳的自动故障切换,支持读写分离,支持mysql主从,基于Nio管理线程的高并发… 详见官网:http://www.mycat.i ...
- linux ssh keys
1. 原理: SSH 密钥对总是成双出现的,一把公钥,一把私钥.公钥可以自由的放在您所需要连接的 SSH 服务器上,而私钥必须稳妥的保管好. 所谓"公钥登录",原理很简单,就是用户 ...
- c++11 条件变量 生产者-消费者 并发线程
http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-vari ...