在多个独立的hashMap对象中搜索特定的键 [英] searching for specific keys in multiple independent hashMap objects
问题描述
我有一个稍微理论上的问题,我想在我开始编程我的解决方案之前进行清理......
背景。
我需要在两个MS Access文件之间进行比较。
每个文件都应该包含在其他文件中找到的数据。 / p>
由于我在JDBC中遇到的限制以及连接到Access结果集(它们只能向前滚动!)我创建了'java对象'(类)模拟结果集的结构。
本质上是
我有一个对象可以模拟结果集中的单个记录行(让我们称它为rowSet)
resSet对象然后有一个rowSets的'数组'。
然而,为了加快速度,我捕获了键和索引列中的值并创建'key_Index'的hashMap到相关的rowSet对象。
然后我做了比较。
取第一个resSet对象(用作主),从中收集个人的Key_Index hashmaps(让我们称之为'aKey'...。
现在使用thi s'aKey'对象来搜索其他可用的resSet对象,并查看是否有包含与'aKey'中的值匹配的key_Index的值。
然而,我有只是有一个相当恼人的想法。
如果我使用代码
resSet.get(aKey)
对其中一个resSet对象将我因为'aKey'对象显然不是同一个对象 - 虽然它的内容应该是相同的(即可比较的)。
我不得不说,因为我阅读我的问题,我认为它措辞不好......所以我想我会包括我创建的类的副本......
重要部分:
成员:
挑战 - '结果集'类型对象的数组列表。
方法:
runChallenge()
package KWhite;
/ **
* RScomparator设计用于比较双输入数据库系统的实例,因为经常在本地运行医学试验数据中发生
*。
*
*双重入口是为了确保在输入过程中没有错误,在单独的独立实例中执行
*。 RScolmparator对象特别能够将任意
*个结果集作为其输入(即来自多个独立创建的数据库的查询)
*
*应该认识到,该对象应该可能是称为DBcomparator
*对象的一部分。
*
* /
//在此处导入
//导入记录器类和所需的依赖关系...
import java.util.ArrayList;
import java.util.HashMap;
导入org.apache.log4j.PropertyConfigurator;
导入MrBlue.DB_Table;
导入TawuaiLogger.tawuaiLogger;
public class RScomparator {
//静态变量
//记录器实例
private static final TawuaiLogger.tawuaiLogger errLog = new tawuaiLogger( RScomparator);
//类成员变量
/ **这是ResSet对象的一个选择,它将对数据提出挑战* /
private ArrayList< ResSet_KW>挑战;
/ **被挑战的当前表的名称* /
private String tableName;
/ **用于元数据参考的'table'对象,这可以用于获取列类型等* /
私有DB_Table表;
//这些是我们的报表对象
/ **挑战失败的报表数组* /
private ArrayList< report_KW>失败;
/ **一个错误报告数组,即没有能够创建的挑战者,没有找到等价值* /
private ArrayList< report_KW>错误;
/ **好值的报表数组* / b $ b private ArrayList< report_KW>成功;
/ **这是主类或构造函数
*
*如果它是一个构造函数重命名以反映类的名称
* @param args
* /
public RScomparator(DB_Table t)// TODO根据需要添加参数
{
PropertyConfigurator.configure(Log4j.properties);
// TODO自动生成的方法存根
challenge = new ArrayList< ResSet_KW>();
//为这个挑战场景初始化我们的报告对象
fail = new ArrayList< report_KW>();
errors = new ArrayList< report_KW>();
success = new ArrayList< report_KW>();
table = t;
tableName = t.getTblName();
}
//类方法在这里
/ **
*将结果集对象添加到此比较器中
*
* @param r将结果集对象插入到此挑战中。
*
* /
public void addChallenger(ResSet_KW r)
{
this.challenge.add(r);
}
/ **
*运行比较过程...
*尽管没有返回任何细节,但它会调用其他方法返回值
*
* /
public void runChallenge()
{
// TODO完成此方法,创建一个报告对象方式
//这些是将要比较的2个结果集对象
ResSet_KW gold = new ResSet_KW();
ResSet_KW silver = new ResSet_KW();
//确保挑战者列表中有对象。
if(challenge.size()<2)
{
//它必须有2个对象..
errLog.add(3,没有可用的结果比较表+ this.tableName);
//我们应该创建报告对象。
this.errors.add(new report_KW(tableName));
//跳出该方法。
return;
}
//获取第一行数据
gold = challenge.get(0); //第一个结果集。
//对于结果集中的每一列,搜索其他字符中的同一个键。
for(HashMap< String,String> c:gold.getRS()。 keySet())
{// c是映射中的键值
//遍历挑战对象
for(int i = 1; i< challenge.size(); i ++ )//我们不想使用第一个元素,所以从1开始不是零
{
silver = challenge.get(i);
if(silver.hasKey(c))
{
//元数据引用的临时对象
//如果存在一场比赛
Column_KW a = gold.getRS()。get(c);
Column_KW b = silver.getRS()。get(c);
//比较
a.compareTo(b,this.table);
//从比较中获取报告
(report_KW k:a.getFailure())
{
this.fail.add(k);
for(report_KW k:a.getPassed())
{
this.success.add(k);
for(report_KW k:a.getPassed())
{
this.errors.add(k);
}
}
else
{
break; //返回for循环中的下一项
}
}
}
}
/ **
*创建错误消息创建器的助手方法
* @param附加消息(如果有的话)
* @返回完整消息
* /
private String getErrMessage(String m){
//当前stact trace中的第三个元素应该是调用方法
StackTraceElement caller = Thread.currentThread()。getStackTrace() [3];
String s = m +\ call from line+ caller.getLineNumber()
+\\\
method:+ this.getClass()+。 + caller.getMethodName();
return s;
}
} //结束类别
ps。任何coments我的代码或更多,欢迎
预先感谢
David
编辑:
我刚刚发现这个问题,嵌套的地图或java中的组合键是这将是我的解决方案,创建一个'定制'key_Index对象,然后定义一个hashcode()并等于它的对象。然而,我已经为我的key_index对象使用了一个'hashMap',那么这是否会在我未注意到的地方自动执行?
<你说:
$ b
如果我在其他resSet对象之一上使用了代码resSet.get(aKey),
将会我有问题,因为'aKey'对象显然不是相同的
对象 - 虽然它的内容应该是相同的(即可比较)。
您必须分别执行 equals()
和 hashcode()
。如果对象相等,实现 equals()
, hashcode()
是不够的。 / p>
示例:
$ p $ import java.util.HashMap;
import java.util.Map;
class A {
字符串名称;
整数;
$ b $ public A(String name,Integer number){
super();
this.name = name;
this.number = number;
}
}
class B {
字符串名称;
整数;
public B(String name,Integer number){
super();
this.name = name;
this.number = number;
}
@Override
public boolean equals(Object obj){
if(obj instanceof B){
return obj == this || (name.equals(((B)obj).name)&& number.equals(((B)obj).number));
}
返回false;
}
@Override
public int hashCode(){
return name.hashCode()+ number.hashCode();
public class TestHashMap {
public static void main(String ... args){
A a1 = new A(a,1);
A anotherA1 = new A(a,1);
地图< A,String> as = new HashMap< A,String>();
as.put(a1,a1);
System.out.println(as.get(anotherA1)); // print null
B b1 = new B(b,1);
B anotherB1 = new B(b,1);
地图< B,String> bs = new HashMap< B,String>();
bs.put(b1,b1);
System.out.println(bs.get(anotherB1)); //打印b1
}
}
I have a slightly theoretical question that I want to clear up before I start programing my solution any further...
Background. I need to perform comparisons between 2 (or possible more) MS Access files.
Each file should contain data that is found in one of the others.
Due to the 'limitation' I have encountered with JDBC and connecting to Access result sets (they are only forward scrollable!) I have created 'java objects' (classes) that models the structure of a result set.
in essence I have an object that models a single record line in the result set (lets call it a rowSet) A resSet object then has an 'array' of rowSets.
However to 'speed things up' I catch the values in the key and index columns and create a hashMap of 'key_Index' this to the relevant rowSet object.
Me comparison then does the following.
take the first resSet object (to use as the master), from this collect the individual the Key_Index hashmaps (lets call it 'aKey'....
Now use this 'aKey' object to search into the other avalailable resSet objects and see if any contain a value of a key_Index that matches the values in 'aKey'.
However I have just had a rather annoying thought.
If I use the code resSet.get(aKey) on one of my other resSet objects will I have problems as the 'aKey' object is obviously not the same object - although it's contents should be the same (ie comparable).
I have to say that as I read my question I think it is not well worded... so I think I will include a copy of the class that I have created...
The important parts:
members: challenge - an arrayList of 'result set' type objects.
method: the runChallenge()
package KWhite;
/**
* the RScomparator is designed for the instance of comparing a double entry database system, as
* often occurs in localy run medical trials data.
*
* The double entry is to ensure that there are no errors made during input, the entry is performed
* in separate independant instances. The RScolmparator object is specifically able to take any
* number of result sets as its input (ie queries from multiple independantly created databases)
*
* It should be recognised that this object should probably be called as part of a DBcomparator
* object.
*
*/
//imports here
//import of logger class and required dependencies...
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.log4j.PropertyConfigurator;
import MrBlue.DB_Table;
import TawuaiLogger.tawuaiLogger;
public class RScomparator {
//Static variables
//the logger instance
private static final TawuaiLogger.tawuaiLogger errLog = new tawuaiLogger("RScomparator");
//class member variables
/** this is a selection of ResSet objects that are going to have thier data challenged */
private ArrayList<ResSet_KW> challenge;
/**the name of the current table being challenged*/
private String tableName;
/**a 'table' object for meta data reference purposes, this can be used for getting column types etc */
private DB_Table table;
//These are our report objects
/**a report array for challenge failures */
private ArrayList<report_KW> fail;
/**a report array for errors, ie no challenger able to be made, no equivalent value found */
private ArrayList<report_KW> errors;
/**a report array for the good values */
private ArrayList<report_KW> success;
/** this is either the main class or the constructor
*
* If it is a constructor rename to reflect the name of the class
* @param args
*/
public RScomparator(DB_Table t) //TODO add arguments as required
{
PropertyConfigurator.configure("Log4j.properties");
// TODO Auto-generated method stub
challenge = new ArrayList<ResSet_KW>();
//initialise our report objects for this challenge scenario
fail = new ArrayList<report_KW>();
errors = new ArrayList<report_KW>();
success = new ArrayList<report_KW>();
table = t;
tableName = t.getTblName();
}
//class methods go here
/**
* add a result set object into this comparator
*
* @param r the result set object being inserted into this challenge.
*
*/
public void addChallenger(ResSet_KW r)
{
this.challenge.add(r);
}
/**
* this runs the comparison process...
* Although no details in of itself are returned it calls other methods that do return a value
*
*/
public void runChallenge()
{
//TODO finish this method, creating a report object on the way
//these are the 2 result set objects that will be compared
ResSet_KW gold = new ResSet_KW ();
ResSet_KW silver = new ResSet_KW ();
//ensure the challenger list has objects in it.
if(challenge.size() < 2)
{
//it must have 2 objects..
errLog.add(3, "there are no results available for comparison of table " + this.tableName);
//either way we should create report object.
this.errors.add( new report_KW(tableName));
//break out of the method.
return;
}
//get the first row of data
gold = challenge.get(0);//the first result set.
//for each column in the result set, perform a search for the same key in the others..
for(HashMap<String, String> c : gold.getRS().keySet())
{//c is the key value in the map
//cycle over the challenge object
for (int i=1; i<challenge.size(); i++)//we don't want to use the first element, so start from 1 not zero
{
silver = challenge.get(i);
if (silver.hasKey(c))
{
//a temp object for meta data referencing
//only get the actual result values if there is a match
Column_KW a = gold.getRS().get(c);
Column_KW b = silver.getRS().get(c);
//make the comparison
a.compareTo(b, this.table);
//get the reports from the comparison
for(report_KW k :a.getFailure())
{
this.fail.add(k);
}
for(report_KW k :a.getPassed())
{
this.success.add(k);
}
for(report_KW k :a.getPassed())
{
this.errors.add(k);
}
}
else
{
break;//return to the next item in the for loop
}
}
}
}
/**
*a helper method to create the error message creator
*@ param m the extra message if any,
*@return s the full message
*/
private String getErrMessage(String m) {
//the third element in the current stact trace should be the calling method
StackTraceElement caller = Thread.currentThread().getStackTrace()[3];
String s = m + "\ncalled from line " + caller.getLineNumber()
+ "\nmethod: " + this.getClass() + "." + caller.getMethodName();
return s;
}
}//end class
ps. any coments on my code or more that welcome
Thanks in advance
David
edit: I just found this question, Nested Maps or combined keys in java is this going to be my solution, create a'custom' key_Index object and then define a hashcode() and equals object for it. However I am allready using a 'hashMap' for my key_index object, so does this perform this automatically somewhere that I haven' noticed?
You said :
If I use the code resSet.get(aKey) on one of my other resSet objects will I have problems as the 'aKey' object is obviously not the same object - although it's contents should be the same (ie comparable).
You have to implement equals()
and hashcode()
respectively. It is not enough to implement equals()
, hashcode()
must be the same if the objects are equal.
Example:
import java.util.HashMap;
import java.util.Map;
class A {
String name;
Integer number;
public A(String name, Integer number) {
super();
this.name = name;
this.number = number;
}
}
class B {
String name;
Integer number;
public B(String name, Integer number) {
super();
this.name = name;
this.number = number;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof B) {
return obj == this || (name.equals(((B) obj).name) && number.equals(((B) obj).number));
}
return false;
}
@Override
public int hashCode() {
return name.hashCode() + number.hashCode();
}
}
public class TestHashMap {
public static void main(String... args) {
A a1 = new A("a", 1);
A anotherA1 = new A("a", 1);
Map<A, String> as = new HashMap<A, String>();
as.put(a1, "a1");
System.out.println(as.get(anotherA1)); // prints null
B b1 = new B("b", 1);
B anotherB1 = new B("b", 1);
Map<B, String> bs = new HashMap<B, String>();
bs.put(b1, "b1");
System.out.println(bs.get(anotherB1)); // prints b1
}
}
这篇关于在多个独立的hashMap对象中搜索特定的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!