Java集合的实现细节—Set集合和Map集合
- Set:代表无序、不可重复的集合
- Map:代表key-value对集合,也称为关联数组
从表面上看,Set和Map相似性很少,但实际上可以说Map集合时Set集合的扩展。
1、Set集合和Map集合的继承体系
Set集合的继承体系
Map集合的继承体系
2、Set集合和Map集合的关系
仔细观察上面两张图,可以发现以下规律:
- Set <---> Map
- EnumSet <---> EnumMap
- SortedSet <---> SortedMap
- TteeSet <---> TreeMap
- NavigableSet <---> NavigableMap
- HashSet <---> HashMap
- LinkedHashSet <---> LinkedHashMap
以上的关系绝对不是偶然的,Map集合的key不能重复,而且也是无序的。亦即Map集合中的key可以组成一个Set集合。实际上,Map集合提供了如下方法返回key所组成的Set集合。
- Set<K> keySet()
由此,即可实现从Map到Set的转换。其实,还可以实现从Set到Map的扩展——Map集合就相当于一个Set集合,只是此时Set集合中的元素都是key-value对。如下图所示:
Map集合示意图 将关联数组的key-value对捆绑在一起
3、实现把Set扩展成“Map”集合
为了把Set扩展成“Map”,可以考虑重新定义一个SimpleEntry类,使用这个类来代表一个key-value对。当Set集合的元素都是SimpleEntry对象时,该Set集合就变成了“Map”集合。
SimpleEntry.java
import java.io.Serializable;
import java.util.Map.Entry; public class SimpleEntry<K, V> implements Entry<K, V>, Serializable {
private final K key;
private V value; public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
} public SimpleEntry(Entry<? extends K, ? extends V> entry) {
this.key = entry.getKey();
this.value = entry.getValue();
} @Override
public K getKey() {
return key;
} @Override
public V getValue() {
return value;
} @Override
public V setValue(V value) { //改变key-value对的value值
V oldValue = this.value;
this.value = value;
return oldValue;
} @Override
public boolean equals(Object obj) { //根据key比较两个SimpleEntry是否相等
if(obj == this) {
return true;
}
if(obj.getClass() == SimpleEntry.class) {
SimpleEntry se = (SimpleEntry)obj;
return se.getKey().equals(getKey());
}
return false;
} //根据key计算hashCode
public int hashCode() {
return key == null ? 0 : key.hashCode();
} public String toString() {
return key + "=" + value;
}
}
Set2Map.java:继承HashSet实现一个Map
import java.util.HashSet;
import java.util.Map;
import java.util.Iterator; public class Set2Map<K, V> extends HashSet<SimpleEntry<K, V>> {
//实现清空所有key-value对的方法
public void clear() {
super.clear();
} //判断是否包含某个key
public boolean containsKey(K key) {
return super.contains(new SimpleEntry<K, V>(key, null));
} //判断是否包含某个value
boolean containsValue(V value) {
for(SimpleEntry<K, V> se : this) {
if(se.getValue().equals(value)) {
return true;
}
}
return false;
} //根据key找出value
public V get(K key) {
for(SimpleEntry<K, V> se : this) {
if(se.getKey().equals(key)) {
return se.getValue();
}
}
return null;
} //将key-value对放入集合中
public V put(K key, V value) {
add(new SimpleEntry<K, V>(key, value));
return value;
} //将另一个Map的key-value对放入该Map中
public void putAll(Map<? extends K, ? extends V> m) {
for(K key : m.keySet()) {
add(new SimpleEntry<K, V>(key, m.get(key)));
}
} //根据指定的key删除对应的key-value对
public V removeENtry(Object key) {
for(Iterator<SimpleEntry<K, V>> it = this.iterator(); it.hasNext(); ) {
SimpleEntry<K, V> en = (SimpleEntry<K, V>)it.next();
if(en.getKey().equals(key)) {
V v = en.getValue();
it.remove();
return v;
}
}
return null;
} //获取key-value对的总数
public int size() {
return super.size();
}
}
上面两段代码中的粗体部分定义了一个先是定义了一个
SimpleEntry<K, V>类。当一个Set集合中的所有元素都是SimpleEntry<K, V>对象时,该Set就变成了一个Map<K, V>集合。
接下来,程序以HashSet<SimpleEntry<K, V>>为父类派生了一个子类Set2Map<K, V>,这个Set2Map<K, V>扩展类完全可以被当成Map使用,因此Set2Map<K, V>中也提供了Map集合应该提供的绝大部分方法。
Set2MapTest.java:测试扩展出来的“Map”集合
public class Set2MapTest {
public static void main(String[] args) {
Set2Map<String, Integer> scores = new Set2Map<String, Integer>(); //将key-value对放入集合中
scores.put("C", 70);
scores.put("C++", 80);
scores.put("Java", 90);
//输出集合中的内容
System.out.println(scores); //访问Map集合中的key-value对
System.out.println("key-value对的数目:" + scores.size());
scores.removeENtry("C");
System.out.println("删除key为\"C\"的Entry之后:" + scores); //根据key取出value
System.out.println("C++的成绩:" + scores.get("C++")); //判断是否包含指定的key
System.out.println("是否包含\"Java\"key:" + scores.containsKey("Java")); //判断是否包含指定的value
System.out.println("是否包含 100 value:" + scores.containsValue(100)); //清空集合
scores.clear();
System.out.println("清空集合后:" + scores);
}
}
运行结果:
由此可以看出,只要对Set稍做改造,就可将Set改造成可以和系统媲美的Map集合。
Java集合的实现细节—Set集合和Map集合的更多相关文章
- 【读书笔记】【深入理解ES6】#7-Set集合和Map集合
ES6新标准中将Set集合和Map集合添加到JS中. ES5中Set集合和Map集合 在ES5中,开发者们用对象属性来模拟这两种集合. var set = Object.create(null); s ...
- 编写Java程序,使用List集合和Map集合输出 市和区
如图: 代码: import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java ...
- Java List集合和Map集合的综合应用
public static void main(String[] args) { //--------------------------------------------------------- ...
- 【spring set注入 注入集合】 使用set注入的方式注入List集合和Map集合/将一个bean注入另一个Bean
Dao层代码: package com.it.dao; public interface SayHell { public void sayHello(); } Dao的Impl实现层: packag ...
- java基础33 Set集合下的HashSet集合和TreeSet集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...
- Collection集合和Collection集合常用功能
Collection集合常用功能 方法: boolean add(E e); 向集合中添加元素 boolean remove(E e); 删除集合中的某个元素 void clear(); 清空集合所有 ...
- JAVA枚举操作(获取值,转map集合)
JAVA枚举相对来说比.NET的枚举功能强大,感觉就像是一种简化版的类对象,可以有构造方法,可以重载,可以继承接口等等,但不能继承类,JAVA枚举在实际开发中应用相当频繁,以下几个封装方法在实际开发中 ...
- Java分享笔记:使用entrySet方法获取Map集合中的元素
/*--------------------------------- 使用entrySet方法取出Map集合中的元素: ....该方法是将Map集合中key与value的关系存入到了Set集合中,这 ...
- Java分享笔记:使用keySet方法获取Map集合中的元素
/*--------------------------- Map集合中利用keySet方法获取所有的元素值: ....keySet方法:将Map中的所有key值存入到Set集合中, ....利用Se ...
随机推荐
- 解决 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
"Accept-Encoding": "gzip, deflate", 这条信息代表本地可以接收压缩格式的数据,而服务器在处理时就将大文件压缩再发回客户端,IE ...
- css样式-表格优化
1.表格的初步优化 index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...
- MYSQL存储过程和函数学习笔记
学至Tarena金牌讲师,金色晨曦科技公司技术总监沙利穆课程笔记的综合. 1. 什么是存储过程和函数 将SQL语句放入一个集合里,然后直接调用存储过程和函数来执行已经定义好的SQL语句,通过存储过程和 ...
- phpstorm xdebug调试设置样式
由于本人比较喜欢白底的phpstorm开发环境,所以XDEBUG断点调试,F8时默认是没有背景色的,phpstorm中的设置方式如下 files -> settings -> Editor ...
- [深入React] 7.组件生命周期
生命周期一共分三段:初始化,运行中,销毁.按照顺序: 初始化 getDefaultProps():Object 全局只会调用一次,为当前类生成的默认props,会被父组件传入的同名props覆盖. g ...
- Linux命令之exit
本文链接:http://codingstandards.iteye.com/blog/836625 (转载请注明出处) 用途说明 exit命令用于退出当前shell,在shell脚本中可以终止当前 ...
- IE6下的怪异解析知识点补充
转载请注明出处:HTMl5自由者
- html拼接数据的时候一定要注意null值的问题
后台会返回null文本 如果直接拼接 不仅仅格式问题 前台会显示null 如果是图片 用fiddle抓取 还会发现你请求了一个带域名/null的接口 所以要把null格式化为空文本
- Querylayer(查询图层) - 浅谈
Querylayer(查询图层)是通过 SQL 查询定义的图层或独立表.通过 Querylayer 可将空间信息和非空间信息都存储在DBMS 中,从而使这些信息可以轻松地整合到 ArcMap 中的各 ...
- COM 浅谈
ArcObject 是基于 COM(Microsoft Component Object Model),即组件对象模型.虽然ArcGIS的终端用户不用理解什么是COM,但是作为基于ArcObject的 ...