- 浏览: 78163 次
- 性别:
- 来自: 上海
最新评论
-
rockythd:
视界这个概念终于搞清楚了,谢谢!
Java关于Scala的“视界(view bound)”的模拟 -
regular:
写了一个更通用的方法:ObjectUtils.cast。目的是 ...
Java关于Scala的“视界(view bound)”的模拟 -
lrztiancai:
谢谢分享。正在找这个!
Parsley+SpiceLib 2.4 Developer Manual -
kraft:
第二版什么时候出啊
Programming In Scala 翻译 -
justjavac:
xpf7622 写道haixu.huang@live @前的名 ...
Programming In Scala 翻译
方案背景
所谓“MultiKeyedMap”是指允许多个关键字经过组合映射到一个对象的集合类。
比方说,我们有一个数据表,大概的结构如下:
数据结构大体如下:
OK,这里,如果ID是关键字的话,可以做出下面的映射:
代码所见,这里你能做的唯一操作就是根据ID号查找人员信息。不过如果你要做特殊条件的查找,比方说:男性的?或者,姓王的?或者姓王的男性?对不起,此功能暂不提供。
假如是MultiKeyedMap的话,那么ID,姓,名,性别,生日都可以作为单独或任意组合的查询的条件从Map里面拣出所需对象(集合)。
这么说,感觉有点儿像我之前提交过的Object数组到泛型数组转换的伪解决方案里面的场景,都是做数据查询的例子。
技术难点
MultiKeyedMap的主要技术难点在于,每个Key都是独立的信息,也就是说,如果压缩了Key信息的存储空间,就必须使用更多的时间做计算;如果想要更快的获得结果,就必须提供给Key信息更多的空间。
技术方案
以下给出两套技术方案:
第一套:时间换空间
第二套:空间换时间
其它
说句实话,第二套方案的实质不是MultiKeyedMap,其思想应该算是MultiMap,也就是一个key映射多个value。
最初我只想到了第一套方案。不过觉得性能上似乎不是很好。之后也参详了Apache Commons Collections库里面的MultiKeyMap,不过这个类更多的花头似乎是在装璜模式上,多个key必须齐全的情况下才能找到对象,不能做到凭1..n-1个key寻找对象集合。
后来学习了Google的Collections里面的MultiMap,看到了“key <-1 = n-> value”的想法,于是转变思路,发现这也是一个方案。就写了这篇文章纪念一下。
实现代码
废话少说,以下是第二套方案的demo实现。只是原型,不保证bug-free。有需要的自行取用。
所谓“MultiKeyedMap”是指允许多个关键字经过组合映射到一个对象的集合类。
比方说,我们有一个数据表,大概的结构如下:
ID | 姓 | 名 | 性别 | 出生日期 |
1 | 王 | 小毛 | 男 | '1973-05-18' |
2 | 沈 | 佩佩 | 女 | '1976-06-24' |
数据结构大体如下:
class Person // 个人信息 { private final Integer id; private String lastName; private String firstName; private Gender gender; private Date birthDate; } enum Gender // 性别枚举 { MALE, FEMALE; }
OK,这里,如果ID是关键字的话,可以做出下面的映射:
import static Gender; void init() { Person wang = new Person(1, "王", "小毛", MALE, Date.parse('1973-05-18')); Person shen = new Person(2, "沈", "佩佩", FEMALE, Date.parse('1976-06-24')); // ... Map hrInfo = new TreeMap(); // TreeMap比较节省空间 hrInfo.put(wang.getId(), wang); hrInfo.put(shen.getId(), shen); // ... } Person checkHrInfo(int id) { return hrInfo.get(id); }
代码所见,这里你能做的唯一操作就是根据ID号查找人员信息。不过如果你要做特殊条件的查找,比方说:男性的?或者,姓王的?或者姓王的男性?对不起,此功能暂不提供。
假如是MultiKeyedMap的话,那么ID,姓,名,性别,生日都可以作为单独或任意组合的查询的条件从Map里面拣出所需对象(集合)。
这么说,感觉有点儿像我之前提交过的Object数组到泛型数组转换的伪解决方案里面的场景,都是做数据查询的例子。
技术难点
MultiKeyedMap的主要技术难点在于,每个Key都是独立的信息,也就是说,如果压缩了Key信息的存储空间,就必须使用更多的时间做计算;如果想要更快的获得结果,就必须提供给Key信息更多的空间。
技术方案
以下给出两套技术方案:
第一套:时间换空间
- 把关键字组成一个对象,实现hashcode方法。然后用这个对象作为key保存映射关系。
- 如果查找若干(非全部)关键字组合条件的信息,则首先要把缺失关键字的所有可能都找出来,形成完整关键字(的hashcode),查找对象集合。
第二套:空间换时间
- 按照key的类型数量建立映射表。比方说,ID | 姓 | 性别 | 生日,就建立4个映射表。然后每个映射表以key为键,保留key对应的所有对象的set为值。
- 查找任意组合key的值时候,比方说,null | "王" | MALE | null,取出非null的key,找到对应的set,然后,取出另一个非null的key,找到对应set,两个set做交集。
其它
说句实话,第二套方案的实质不是MultiKeyedMap,其思想应该算是MultiMap,也就是一个key映射多个value。
最初我只想到了第一套方案。不过觉得性能上似乎不是很好。之后也参详了Apache Commons Collections库里面的MultiKeyMap,不过这个类更多的花头似乎是在装璜模式上,多个key必须齐全的情况下才能找到对象,不能做到凭1..n-1个key寻找对象集合。
后来学习了Google的Collections里面的MultiMap,看到了“key <-1 = n-> value”的想法,于是转变思路,发现这也是一个方案。就写了这篇文章纪念一下。
实现代码
废话少说,以下是第二套方案的demo实现。只是原型,不保证bug-free。有需要的自行取用。
public interface MultiKeyedMap { void put(Object[] keys, Object value); MultiKeyedEntry[] get(Object[] keys); boolean containsKey(int keyIndex, Object key); }
public class MultiKeyedEntry implements Comparable { private final Object[] keys; private Object value; MultiKeyedEntry(Object[] keys) { this.keys = keys; } public Object[] getKeys() { return this.keys; } public boolean equals(Object o) { if (o instanceof MultiKeyedEntry) { MultiKeyedEntry mk = (MultiKeyedEntry) o; if (mk.keys.length != keys.length) { return false; } for (int i = 0; i < keys.length; i++) { Object k = mk.keys[i]; Object _k = keys[i]; if (k != null && _k != null && !k.equals(_k)) { return false; } } return true; } return false; } /* * (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object o) { MultiKeyedEntry e = (MultiKeyedEntry) o; for (int i = 0; i < keys.length; i++) { int n = ((Comparable) keys[i]).compareTo(e.keys[i]); if (n != 0) { return n; } } return 0; } public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < keys.length; i++) { sb.append(", ").append(keys[i]); } sb.append(": ").append(value); return sb.substring(2); } public void setValue(Object value) { this.value = value; } public Object getValue() { return value; } }
public class MultiKeyedMapImpl implements MultiKeyedMap { private final Map[] maps; MultiKeyedMapImpl(int keyCount) { if (keyCount < 1) { throw new IllegalArgumentException(); } maps = new Map[keyCount]; for (int i = 0; i < keyCount; i++) { maps[i] = new HashMap(); } } /* * (non-Javadoc) * @see multimap.MultiKeyedMap#containsKey(int, java.lang.Object) */ public boolean containsKey(int keyIndex, Object key) { return keyIndex >= maps.length ? false : maps[keyIndex].containsKey(key); } /* * (non-Javadoc) * @see multimap.MultiKeyedMap#get(java.lang.Object[]) */ public MultiKeyedEntry[] get(Object[] keys) { validateKeyCount(keys); Collection c = null; for (int i = 0; i < maps.length; i++) { Object key = keys[i]; if (key != null) { Set valueSet = (Set) maps[i].get(key); if (valueSet == null) { return new MultiKeyedEntry[0]; } if (c == null) { c = new LinkedHashSet(valueSet); } else { c.retainAll(valueSet); if (c.size() == 0) { return new MultiKeyedEntry[0]; } } } } if (c == null) { c = new LinkedHashSet(); Collection v = maps[0].values(); for (Iterator it = v.iterator(); it.hasNext();) { c.addAll((Set)it.next()); } } return (MultiKeyedEntry[]) c.toArray(new MultiKeyedEntry[c.size()]); } /* * (non-Javadoc) * @see multimap.MultiKeyedMap#put(java.lang.Object[], java.lang.Object) */ public void put(Object[] keys, Object value) { validateKeyCount(keys); MultiKeyedEntry entry = new MultiKeyedEntry(keys); entry.setValue(value); for (int i = 0; i < maps.length; i++) { if (keys[i] == null) { throw new IllegalArgumentException(); } Set set = (Set) maps[i].get(keys[i]); if (set == null) { set = new TreeSet(); maps[i].put(keys[i], set); } set.add(entry); } } private void validateKeyCount(Object[] keys) { if (keys.length != maps.length) { throw new IllegalArgumentException(); } } }
public class TripleKeyedMap extends MultiKeyedMapImpl { TripleKeyedMap() { super(3); } public void put(Object key1, Object key2, Object key3, Object value) { put(new Object[] { key1, key2, key3 }, value); } public MultiKeyedEntry[] get(Object key1, Object key2, Object key3) { return get(new Object[] { key1, key2, key3 }); } }
public class Main { private static final Person wang = new Person(1, "王", "小毛", new Date(1973, 4, 18), Gender.MALE), shen = new Person(2, "沈", "佩佩", new Date(1976, 5, 24), Gender.FEMALE), lu = new Person(3, "陆", "小凤", new Date(898, 10, 7), Gender.MALE); public static void main(String[] args) { TripleKeyedMap map = new TripleKeyedMap(); map.put(wang.getLastName(), wang.getBirthDate(), wang.getGender(), wang); map.put(shen.getLastName(), shen.getBirthDate(), shen.getGender(), shen); map.put(lu.getLastName(), lu.getBirthDate(), lu.getGender(), lu); MultiKeyedEntry[] entries = map.get(null, null, Gender.MALE); for (int i = 0; i < entries.length; i++) { System.out.println(entries[i]); } } } class Gender extends Enum { private Gender(String value) { super(value); } public static final Gender MALE = new Gender("MALE"), FEMALE = new Gender("FEMALE"); } class Person { private final int id; private final String lastName; private final String firstName; private final Date birthDate; private final Gender gender; public Person(int id, String lastName, String firstName, Date birthDate, Gender gender) { this.id = id; this.lastName = lastName; this.firstName = firstName; this.birthDate = birthDate; this.gender = gender; } public int getId() { return id; } public String getLastName() { return lastName; } public String getFullName() { return lastName + ", " + firstName; } public Date getBirthDate() { return birthDate; } public Gender getGender() { return gender; } }
abstract public class Enum implements Comparable { // Collection.retainAll方法要求对象必须扩展了Comparable接口 private final String value; public Enum(String value) { this.value = value; } public boolean equals(Object o) { return compareTo(o) == 0; } public String toString() { return value; } public int compareTo(Object o) { if (this.getClass().equals(o.getClass())) { Enum e = (Enum) o; return value == null ? (e.value == null ? 0 : -1) : value.compareTo(e.value); } return -1; } }
发表评论
-
把Spring容器中的bean绑定到通过代码创建的对象
2012-04-26 16:17 2278Spring提供了对配置中创建对象的字段实例注入。但如果是通过 ... -
动态注册消息类型及处理函数
2011-10-01 15:56 1011内容略。参见代码演示。 -
代码实例
2011-02-14 17:17 1040代码实例文件 -
如何在类外部调用被子类覆盖的父类方法
2011-01-20 14:46 1900题目比较绕。以下用一个简单的例子说明: public cl ... -
SWT应用的开发实例:没有使用到OSGi
2011-01-14 11:27 1531添加音效,以及中奖名单回看功能。 SWT应用一枚。具体方法见 ... -
运行期代码问题检查技术的研究
2010-11-29 13:30 1146以下用我之前代码中的一个bug作为说明,解释如何实现代码在运行 ... -
代码潜在故障的动态分析
2010-11-16 12:24 1526引子 大家都听说过FindBugs的大名。这是一款静态代码分析 ... -
健壮的、便捷的、异步的SocketChannel实现
2010-04-27 10:34 8403Socket通信比较常见的问题有如下几种: 1、设置收发超时; ... -
打算研究学习一下OSGi和Equinox
2010-02-10 11:26 1160看到一本很直接讨论这个题目的书,不过要等到3月1日才出来。 ... -
关键应用服务的集群技术模拟
2010-01-08 14:41 1092集群技术,也就是俗称的Cluster,是为了保证某种应用不间断 ... -
JarSpur 检查引用包归属的小工具
2009-12-25 17:31 1087图形化的界面,允许你导入任意多的在项目中可能需要的Jar包。 ... -
class.getResourceAsStream()与ClassLoader.getResourceAsStream()的区别
2009-11-11 17:33 2058在jar包里获得流形式的资源有两种方法,一个是Class.ge ... -
Java2D: 硬件加速 - 第二部分 - 缓冲策略:Buffer Strategies
2009-11-02 12:52 2961原文地址:Java2D: Hardware ... -
Java2D: 硬件加速 - 第一部分 - 非恒定图像类:Volatile Image
2009-10-30 16:19 4300原文地址:Java2D: Hareware Accelerat ... -
自建的MiniChart库,目前实现了点图、折线图、柱状图和饼图
2009-07-15 11:08 1252花了大约一个星期时间做的MiniChart库。 由于现在的免费 ... -
BM方案模式匹配的Java代码实现
2009-06-17 13:47 1590速度还算快,例子里比较的文件一共371个,3,293,472字 ... -
对于经典模式匹配算法的一些改动
2009-06-12 12:44 1501从一个很长的字符串(或者数组)中,查找某个子串(模式串)是否存 ... -
读写进程的互斥锁
2009-03-16 15:27 1592以下的代码完成了对某个资源的读写互斥锁,具体说明如下:1. 若 ... -
Object数组到泛型数组转换的伪解决方案
2009-01-23 10:44 4386闲来无事,想要用目前的Java技术模拟一个对象数据库。最初只是 ...
相关推荐
学生信息管理系统-----------无数据库版本。资源来源于网络分享,如有侵权请告知!
2024年福建省村级(居委会)行政区划shp数据集 坐标系:WGS1984
win32汇编环境,对话框中显示bmp图像文件
基于STM8单片机的编程实例,可供参考学习使用,希望对你有所帮助
电动汽车动力系统匹配计算模型:输入整车参数及性能要求,一键生成驱动系统的扭矩功率峰值转速等参数。 2、整车动力经济性计算模型:包含NEDC WLTC CLTC工况,输入整车参数可生成工况电耗、百公里电耗、匀速工况续航、百公里电耗等信息。 实际项目中使用的计算仿真模型.
2020CCF下降2020 CCF大数据与计算智能大赛-非结构化商业文本信息中隐私信息识别-第7名方案bert base + flat + crf + fgm + swa + pu learning策略 + clue数据集 = test1单模0.906词向量https://github.com/Embedding/Chinese-Word-Vectors SGNS(Mixed-large 综合)loss mask相关代码为pu learning策略的实现主要模块版本 python 3.6.9火炬 1.1.0变压器 3.0.2pytorchcrf 1.2.0torchcontrib 0.0.2
计算机系毕业设计
基于STM8单片机的编程实例,可供参考学习使用,希望对你有所帮助
基于SpringBoot+MySQL图书销售管理系统网上书店项目源码+数据库(高分毕业设计&课程设计) 该项目是个人大作业项目源码,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!!!评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 图书管理系统 框架介绍 依赖 版本 Spring Boot 2 Mybatis Plus 3.5.3 jjwt 0.11.2 vue 2.0 ehcache 2.10.9 系统采用前后端分离,前端打包后放在 /resources/static 目录下面 直接启动后端工程即可访问 系统亮点 采用rsa非对称加密算法生成 jwt认证密钥 springboot集成ehcache作为缓存 采用aop方式记录接口访问日志 使用h2内存数据库,启动应用执行自动建表语句和初始化数据 统一异常和响应进行封装 集成springdoc作为接口文档 系统访问 http://wholevoid.com:9090/ 用户名及密码 admin/123456 图书管理系统 框
二极管钳位三电平VSG仿真模型 1.加入中点电位平衡 2.仿真有视频教程 3.THD均<5% 可以在此模型的基础上加入自适应控制、模型预测控制等等
基于Halcon的机器视觉试验平台的设计与研究 20181126
腾讯云开发者工具套件(SDK)3.0,SDK3.0是云 API3.0 平台的配套工具。目前已经支持cvm、vpc、cbs等产品,后续所有的云服务产品都会接入进来。新版SDK实现了统一化,具有各个语言版本的SDK使用方法相同,接口调用方式相同,统一的错误码和返回包格式这些优点。 为方便 Python 开发者调试和接入腾讯云产品 API,这里向您介绍适用于 Python 的腾讯云开发工具包,并提供首次使用开发工具包的简单示例。让您快速获取腾讯云 Python SDK 并开始调用。
说明文档1 队伍简介初赛名次第42名复赛名次第22名队伍名把球给我两名队员全部来自中国科学院大学2 算法思路首先手工标记第一阶段2015年和2017的图像里的建筑物,将大图像划分成小图像,训练多个模型,识别出图像中的建筑物,不对测试集(第二阶段的图像)进行任何标注,直接在图像上预测,分别识别出2015和2017的建筑物,再将所得的两张建筑物图像相减,对结果文件进行边缘平滑和散点去除即可得出最后的结果。切割成160*160、224*224、256*256大小的小图片训练模型基于第一阶段的训练数据,分别训练了deeplabv2、resnet_fcn两个模型,分别在3种大小的图像上训练得到了5个模型(由于resnet最小图像限制为197,只用了224和256两种大小的图像),设定输出概率大于0.5判定为建筑物,小于0.5则为非建筑物未在测试数据上进行建筑物标注,线下建筑物识别准确率82%左右,经过标注,建筑物识别准确率能达到90%。复赛初始提交,泛化成绩0.742。经过数据标注和再训练,最终成绩0.829。数据增强用于模型训练阶段,数据后处理是对
tdm64-gcc-5.1.0-2 (不盈利分享)
python语言mp3pl爬虫程序代码XQZQ
三相不平衡电压下T型NPC三电平并网逆变器并网控制 1.采用正负序分离锁相环以及正序PI控制,负序PI控制 2.采用中点电位平衡控制-零序电压注入法 3.采用SVPWM羊角波调制方式 4.提供参考文献 提供仿真源文件,电流环参数设计,正负序分离方法详解,零序电压注入法详解,SVPWM调制原理
Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设),个人经导师指导并认可通过的毕业设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做毕业设计的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设)Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设)Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设)Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设)Java毕业设计-基于SpringBoot的旅游网站项目源码+数据库(高分毕设)Java毕业设计-个人经导师指导并认可通过的毕业设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!个人经导师指导并认可通过的毕业设计项目,评审分98分,项目中的源码都