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 ...
随机推荐
- Python Cookbook笔记
字符串:s.strip() 删除字符串开始和结尾的空白字符. s.lstrip() 删除左边的,s.rstrip() 删除右边的. 随机数:random.random() 生成0-1之间的数. ...
- @JoinTable和@JoinColumn
默认情况下,JPA 持续性提供程序在映射多对多关联(或在单向的一对多关联中)的拥有方上的实体关联时使用一个连接表.连接表名称及其列名均在默认情况下指定,且 JPA 持续性提供程序假设:在关系的拥有方上 ...
- 浅谈C++中的那些内存泄露
尽管学过C语言.可是C++里面的一些基础还是不太懂,还须要再掌握. 老范也開始要讲C++设计模式了,必须快点看了.不然就要白花窝滴钱了. 对于内存泄露,我的个人理解就是程序在执行过程中,自己开辟了空间 ...
- Linux实现密钥登陆
公司为了安全,一直都采用密钥登陆远程SSH,现在有了自己的服务器,自己又学者配了一把,下面就是配置笔记. 1.登陆未设置密钥的Linux服务器 2.工具新建用户密钥生成向导 3.选择生成密钥的加密方式 ...
- 把Nginx加入系统服务 service nginx (start | stop | restart | reload)
vim /etc/init.d/nginx 1 #!/bin/bash 2 # nginx Startup script for the Nginx HTTP Server 3 # it is v ...
- 毕业设计 ASP.Net+EasyUI开发 X X露天矿调度管理信息系统(一)
开篇介绍关于EasyUI技术,界面部分的一些使用知识,包括控件的赋值.取值.清空,以及相关的使用. 我们知道,一般Web界面包括的界面控件有:单行文本框.多行文本框.密码文本框.下拉列表Combobo ...
- Android --------- 命名规范
工程 软件名称,最好是英文首字母大写:如MobileSafe. 包 企业单位网址的倒序+软件名称:如com.baidu.mobilesafe. 类 类中分为:(头字母小写,其他每个单子首字母大写) 1 ...
- Swift--集合类型 数组 字典 集合
数组 1.创建一个数组 var someInts = [Int]()空数组 someInts = []清空 var threeDoubles = Array(repeating: 0.0, count ...
- Xcode7 iOS9网络配置
iOS9为了增强数据访问安全,将所有的http请求都改为了https,为了能够在iOS9中正常使用地图SDK,请在"Info.plist"中进行如下配置,否则影响SDK的使用. & ...
- SignalR2.0开发实例之——私聊
一.前言 继续上一章的补充,这章介绍使用私聊的功能.主要通过一个方法 Clients.Client(Context.ConnectionId).showMessage(msg); SignalR框 ...