(一)映射的概念
映射就是存储(键,值)数据对的数据结构(Key,Value)。根据键(Key),寻找
值(Value)
有序映射中的键具有顺序性,基于搜索树实现
无序映射中的键没有顺序性,基于哈希表实现
映射->字典->键值对的集合
f(x)=x^2+3x+2
一个x只能对应一个y
多个x可以对应多个y 也可以对应一个y
一个x可以不可以对应多个y?不可以
x2/a-y2/b=1 方程
函数
x->y 一对一 一对多 多对多
y->x 一对一 一对多 多对多
姓名->ID
单词->释义
学生->学号
[张三 李四 王五]
[10 11 12]
class Person
name
id
[p1,p2,p3]
Key不能重复set value可以重复list
{Key-Value} 键值对
{Key-Value} 键值对
{Key-Value} 键值对
{Key-Value} 键值对
{Key-Value} 键值对
“张三”:120
(二)代码实现
定义map接口
import 顺序表.List;
/*
* 有序映射中的键具有顺序性,基于搜索树实现
无序映射中的键没有顺序性,基于哈希表实现
*/
public interface Map<K,V> {
void add(K key,V value);//添加一个键值对
V remove(K key);//移除键
boolean contains(K key);
V get(K key);//根据键获取值
void set(K key,V value);
int getSize();
boolean isEmpty();
public Set keys(); //返回映射中键的集合
public List values(); //返回映射中值的线性表
}
实现LinkedListmap
import p02.动态链表.SingleLinkList;
import 顺序表.List;
public class LinkedListMap<K, V> implements Map<K, V> {
/*
* 定义Node结点
*/
private class Node {
K key;
V value;
Node next;
public Node(K key, V value) {
this.key = key;
this.value = value;
next = null;
}
public Node() {
// TODO Auto-generated constructor stub
this(null, null);
}
}
public Node head;// 虚拟头结点
public int size;
public LinkedListMap() {
// TODO Auto-generated constructor stub
head = new Node();
size = 0;
}
@Override
public void add(K key, V value) {// 添加元素
// TODO Auto-generated method stub
/*
* 首先找要插入的键,如果这个键不存在,就添加,负责就只改value
*/
Node node = getNode(key);
if (node == null) {
node = new Node(key, value);
// 头插法
node.next = head.next;
head.next = node;
size++;
} else {
node.value = value;
}
}
@Override
public V remove(K key) {
// TODO Auto-generated method stub
Node p = head;
while (p.next != null) {
if (p.next.equals(key)) {
break;
}
p = p.next;
}
if (p.next != null) {
Node temp = p.next;
p.next = temp.next;
temp.next = null;
size--;
return temp.value;
}
return null;
}
@Override
public boolean contains(K key) {
// TODO Auto-generated method stub
return getNode(key) != null;
}
@Override
public V get(K key) {
// TODO Auto-generated method stub
Node node = getNode(key);
return node == null ? null : node.value;
}
/*
递归实现
* private Node getNode(K key, Node node) {// 可能会出错 // TODO Auto-generated
* method stub if (node.key.equals(key)) { return node; } if (node.next != null)
* { getNode(key, node.next); } return null; }
*/
private Node getNode(K key) {
Node cur = head.next;
while (cur != null) {
if (cur.key.equals(key)) {
return cur;
}
cur = cur.next;
}
return null;
}
@Override
public void set(K key, V value) {// 设置键值对
// TODO Auto-generated method stub
/*
* 首先键值对得存在
*/
Node node = getNode(key);
if (node == null) {
throw new IllegalArgumentException("键值对不存在,不能修改。");
}
node.value = value;
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return getSize() == 0;
}
@Override
public Set keys() {// 得到键
// TODO Auto-generated method stub
Set<K> set = new LinkedSet<K>();
Node cur = head.next;
while (cur != null) {
set.add(cur.key);
}
return set;
}
@Override
public List values() {
// TODO Auto-generated method stub
List<V> list = new SingleLinkList<>();
Node cur = head.next;
while (cur != null) {
list.addLast(cur.value);
}
return list;
}
}
测试:用map映射找一本书中一个单词出现的次数。
import java.util.ArrayList;
/*
* 测试链表实现的映射
* 统计一本书中一个单词出现的次数
*/
public class Test3 {
public static void main(String[] args) {
ArrayList<String> words=new ArrayList<>();
FileOperation.readFile("a-tale-of-two-cities.txt", words);
long start=System.currentTimeMillis();
LinkedListMap<String, Integer> map=new LinkedListMap<>();
//BstMap<String, Integer> map=new BstMap<>();
for(int i=0;i<words.size();i++){
String word=words.get(i);
if(map.contains(word)){
map.set(word, map.get(word)+1);//如果包含,次数加1
}else{
map.add(word, 1);
}
}
long end=System.currentTimeMillis();
double second=(end-start)/1000.0;
System.out.println("用时:"+second);
System.out.println("所有单词的个数"+words.size());
System.out.println("map的长度(不重复的单词数):"+map.getSize());
System.out.println("she:"+map.get("she"));
//System.out.println(map.keys());
}
}