Java HashMap内容似乎在不改变它的情况下改变了
我有一个关于Java中HashMap的问题。为了详细解释这个问题,我将首先发布一些您可以参考的代码Java HashMap内容似乎在不改变它的情况下改变了,java,hashmap,Java,Hashmap,我有一个关于Java中HashMap的问题。为了详细解释这个问题,我将首先发布一些您可以参考的代码 public void BLASTroute(String args[]) throws IOException, InterruptedException{ ... correctMapping CM = new correctMapping(); CM.correctMapping(RB.BLASTresults, exi
public void BLASTroute(String args[]) throws IOException, InterruptedException{
...
correctMapping CM = new correctMapping();
CM.correctMapping(RB.BLASTresults, exists);
CalculateNewConsensusSequence CNCS =
new CalculateNewConsensusSequence();
char[] consensus = CNCS.calculateNewConsensusSequence(
CM.newSeq, CM.remindGaps, EMBLreaderReference.sequence, exists);
HashMap<Integer, ArrayList<String>> gapsFused =
new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
GenerateGeneLists GGL = new GenerateGeneLists(
EMBLreaderReference, CM.newSeq, gapsFused, exists,
GQList, allMappedPositions);
System.out.println(CM.remindGaps.hashCode());
gapsFused=GGL.generateGeneListSNP(gapsFused);
System.out.println(CM.remindGaps.hashCode());
System.out.println(gapsFused.hashCode());
GGL.generateGeneListFrameShift(gapsFused);
}
public void BLASTroute(字符串args[])引发IOException、InterruptedException{
...
correctMapping CM=新的correctMapping();
CM.correctMapping(RB.BLASTresults,存在);
CalculateNewConsensusequence CNCS=
新的CalculateNewConsensuseSequence();
char[]共识=CNCS.calculatenewconsensusequence(
存在CM.newSeq、CM.remendinggaps、EMBLreaderReference.sequence);
HashMap间隙融合=
新的HashMap();
for(整数i:CM.keySet()){
ArrayList newList=CM.remendinggaps.get(i);
gapsFused.put(i,newList);
}
GenerateGeneLists GGL=新的GenerateGeneLists(
EMBLreaderReference,CM.newSeq,gapsFused,存在,
GQList,所有映射位置);
System.out.println(CM.rementgaps.hashCode());
gapsFused=GGL.generateGeneListSNP(gapsFused);
System.out.println(CM.rementgaps.hashCode());
System.out.println(gapsFused.hashCode());
generateGeneListFrameShift(gapsFused);
}
发生以下情况:
在我的类correctMapping中,我填充了一个名为rementgaps的全局变量。我后来在一些函数中使用了它,但没有发生任何事情/一切都按预期进行
然后,我复制了一个名为gapsFused的HashMap(我不知道这是否与我的问题有关)
现在有一个有趣的部分:在GenerateGeneList类中,我不使用HashMap
但是,在执行函数generateGeneListSNP后,提示间隔已更改!我也会为您发布代码,以便您能更好地帮助我:
public GenerateGeneLists(EMBL_reader EMBLreaderReference,
HashMap<String,ArrayList<String>> newSeq,
HashMap<Integer,ArrayList<String>> gapsFused, File exists,
ArrayList<GeneQualifier> GQlist,
HashMap<Integer,Integer> allMappedPositions)
throws InterruptedException{
this.EMBLreaderReference=EMBLreaderReference;
this.newSeq=newSeq;
//this.gapsFused=gapsFused;
this.exists=exists;
this.GQlist=GQlist;
this.allMappedPositions=allMappedPositions;
for (GeneQualifier GQ : this.GQlist){
startlist.add(GQ.start);
stoplist.add(GQ.stop);
startMap.put(GQ.start,GQ);
}
}
public HashMap<Integer,ArrayList<String>> generateGeneListSNP(
HashMap<Integer,ArrayList<String>> gapsFused)
throws IOException{
File GQSNP = new File (exists+"/GQsnp.txt");
BufferedWriter SNP = new BufferedWriter(new FileWriter(GQSNP));
SNP.write("#Gene_start\tGene_stop\tlocus_tag\tproduct" +
"\tputative_SNP_positions(putative_changes)\n");
HashMap<GeneQualifier,ArrayList<Integer>> GQreminder =
new HashMap<GeneQualifier,ArrayList<Integer>>();
for (String s : newSeq.keySet()){
ArrayList<String> blub = newSeq.get(s);
char[] qrySeq = blub.get(0).toCharArray();
char[] refSeq = blub.get(1).toCharArray();
int start = Integer.valueOf(blub.get(2));
int stop = Integer.valueOf(blub.get(3));
for (int i=0;i<refSeq.length;i++){
if (qrySeq[i]!=refSeq[i]&&qrySeq[i]!='-'&&qrySeq[i]!='.'){
if (mismatchList.containsKey(start+i)){
ArrayList<Character> blah = mismatchList.get(start+i);
blah.add(qrySeq[i]);
mismatchList.put(start+i, blah);
}
else {
ArrayList<Character> blah = new ArrayList<Character>();
blah.add(qrySeq[i]);
mismatchList.put(start+i,blah);
}
}
else if (qrySeq[i]!=refSeq[i]&&(qrySeq[i]=='-'||qrySeq[i]=='.')){
if (!gapsFused.containsKey(start+i)){
ArrayList<String> qwer = new ArrayList<String>();
qwer.add(String.valueOf(qrySeq[i]));
gapsFused.put(start+i,qwer);
}
else {
ArrayList<String> qwer = gapsFused.get(start+i);
qwer.add(String.valueOf(qrySeq[i]));
gapsFused.put(start+i,qwer);
}
if (!deletionPositionsAndCount.containsKey((start+i))){
int count = 1;
deletionPositionsAndCount.put(start+i, count);
}
else {
int count = deletionPositionsAndCount.get(start+i);
count = count+1;
deletionPositionsAndCount.put(start+i, count);
}
}
}
}
for (Integer a : mismatchList.keySet()){
for (int i=0;i<startlist.size();i++){
int start = startlist.get(i);
int stop = stoplist.get(i);
if (a>=start && a<=stop){
GeneQualifier GQ = startMap.get(start);
if (!GQreminder.containsKey(GQ)){
ArrayList save = new ArrayList<Integer>();
save.add(a);
GQreminder.put(GQ,save);
}
else {
ArrayList save = GQreminder.get(GQ);
save.add(a);
GQreminder.put(GQ,save);
}
break;
}
}
}
for (GeneQualifier GQ : GQreminder.keySet()) {
ArrayList<Integer> save = GQreminder.get(GQ);
int start = GQ.start;
int stop = GQ.stop;
String locus_tag =
GQ.geneFeatures.get("locus_tag").get(0).replace("\n", "");
String product =
GQ.geneFeatures.get("product").get(0).replace("\n", "");
SNP.write(start + "\t" + stop + "\t" + locus_tag +
"\t" + product + "\t");
boolean end = false;
for (int i = 0; i < save.size(); i++) {
if (i==save.size()-1) end=true;
int posi = save.get(i);
SNP.write(posi + "(");
ArrayList<Character> mismatches = mismatchList.get(posi);
for (int j = 0; j < mismatches.size(); j++) {
char snipp = mismatches.get(j);
if (j == mismatches.size() - 1) {
SNP.write(snipp + ")");
} else {
SNP.write(snipp + ",");
}
}
if (end == false){
SNP.write(",");
}
}
SNP.write("\n");
}
SNP.close();
return gapsFused;
}
public generategenelist(EMBL_reader emblreader reference,
HashMap newSeq,
HashMap gapsFused,文件存在,
ArrayList GQlist,
HashMap(所有映射位置)
抛出中断异常{
this.EMBLreaderReference=EMBLreaderReference;
this.newSeq=newSeq;
//这个.gapsFused=gapsFused;
this.exists=存在;
this.GQlist=GQlist;
这个.allMappedPositions=allMappedPositions;
for(GeneQualifier-GQ:this.GQlist){
startlist.add(GQ.start);
停止列表。添加(GQ.stop);
startMap.put(GQ.start,GQ);
}
}
公共HashMap generateGeneListSNP(
HashMap(gapsFused)
抛出IOException{
文件GQSNP=新文件(存在+“/GQSNP.txt”);
BufferedWriter SNP=新的BufferedWriter(新文件编写器(GQSNP));
SNP.write(“#Gene_start\t Gene_stop\t焦点标签\t产品”+
“\t交换性SNP位置(假定的变化)\n”);
HashMap GQreminder=
新的HashMap();
对于(字符串s:newSeq.keySet()){
ArrayList blub=newSeq.get(s);
char[]qrySeq=blub.get(0.toCharArray();
char[]refSeq=blub.get(1.toCharArray();
int start=Integer.valueOf(blub.get(2));
int stop=Integer.valueOf(blub.get(3));
对于(int i=0;i您必须记住,在Java中,所有对象都作为引用传递。因此,当您这样做时:
ArrayList<String> newList = CM.remindGaps.get(i);
ArrayList newList=CM.remendinggaps.get(i);
基本上,您将newList指向与remindGaps映射中包含的列表相同的列表。现在,即使您使用gapsFused,对其值的任何更改都会影响内存中相同的基础列表-remindGaps和gapsFused都指向该列表
将您的复制代码更改为以下代码,并查看是否有差异:
ArrayList<String> newList = new ArrayList<String>(CM.remindGaps.get(i));
arraylistnewlist=newarraylist(CM.rementgaps.get(i));
通过这样做,您将创建一个newList将指向的新列表,因此更改将被封装。您的代码非常长且难以阅读(主要是因为它不遵守Java命名约定),但我猜您的问题来自这样一个事实,即您的映射副本只是将ArrayList引用从一个映射复制到另一个映射:
HashMap<Integer, ArrayList<String>> gapsFused = new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
HashMap gapsFused=newhashmap();
for(整数i:CM.keySet()){
ArrayList newList=CM.remendinggaps.get(i);
gapsFused.put(i,newList);
}
在上述代码中,您不创建任何新列表。您只需将相同的列表存储在另一个地图中。如果您需要新列表,则代码应为:
Map<Integer, List<String>> gapsFused = new HashMap<Integer, List<String>>();
for (Integer i : CM.remindGaps.keySet()) {
List<String> newList = new ArrayList<STring>(CM.remindGaps.get(i));
gapsFused.put(i, newList);
}
Map gapsFused=newhashmap();
for(整数i:CM.keySet()){
List newList=newarraylist(CM.remendinggaps.get(i));
gapsFused.put(i,newList);
}
不分析所有代码:
HashMap<Integer, ArrayList<String>> gapsFused = new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
HashMap gapsFused=newhashmap();
for(整数i:CM.keySet()){
ArrayList newList=CM.remendinggaps.get(i);
gapsFused.put(i,newList);
}
在此代码之后,gapFused将包含作为REMENTGAPS条目副本的条目,因此这些条目将引用相同的对象(键和值)。因此,如果您在一个映射中添加或删除条目,则对另一个映射没有影响,但是如果您更改通过一个映射访问它的值,您将看到更改也通过另一个映射访问它(例如remingGaps.get(1).add(“hello”))
代码中使用的名称“newList”令人困惑,因为它不是新列表,只是现有列表上的引用…,因为映射的值是数组列表,而您只是在进行浅拷贝(意味着新的映射
引用了与第一个映射
相同的列表
)第二个映射中列表的更改将反映在第一个映射中。为了避免这种情况,您需要在创建新的映射时对列表进行深度复制,正如我所看到的,您的示例似乎过于冗长,以至于“临时”人员无法接近您应该花一些时间将其缩小到最相关的代码部分。