1

JavaのHashMapに関して問題があります。問題を詳細に説明するために、最初に参照できるコードをいくつか投稿します。

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);

        }

次のことが発生します。

私のクラスcorrectMappingでは、remindGapsというグローバル変数を入力します。後でいくつかの関数で使用しますが、何も起こらず、すべてが期待どおりに機能します。

次に、gapsFusedというHashMapのコピーを作成します(これが私の問題と関係があるかどうかはわかりません)。

ここで興味深い部分があります。GenerateGeneListsクラスでは、remindGapsHashMapでは何もしません。

ただし、関数generateGeneListSNPが実行された後、remindGapsが変更されました。私もあなたのためにコードを投稿しますので、あなたは私をより良く助けることができます:

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;
}

ご覧のとおり、このクラスではremindGapsは使用されていませんが、変更が加えられています。なぜそうなるのか分かりますか?

私がテストしたのは、gapsFused(最初のHashMapの作成されたコピー)を手動で変更した場合にremindGapsが変更されるかどうかです。これは当てはまらないので、コピープロセスがうまくいかなかったとは思いません(たとえば、他のHashMapを指しているか、それを参照しているだけです)。

この問題を解決するために、あなたのアイデアと助けを本当に感謝します。

4

4 に答える 4

3

Javaでは、すべてのオブジェクトが参照として渡されることを覚えておく必要があります。だから、あなたがしたとき:

ArrayList<String> newList = CM.remindGaps.get(i);

基本的に、newListをremindGapsマップに含まれているものと同じリストにポイントしました。これで、gapsFusedを使用している場合でも、その値を変更すると、メモリ内の同じ基になるリストに影響します。これは、remindGapsとgapsFusedの両方が指しているものです。

コピーコードを次のように変更して、違いが生じるかどうかを確認します。

ArrayList<String> newList = new ArrayList<String>(CM.remindGaps.get(i));

これにより、newListが指す新しいリストが作成され、変更がカプセル化されます。

于 2012-06-20T11:16:38.130 に答える
0

コードは非常に長くて読みにくいですが(主に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);
}

上記のコードでは、新しいリストは作成しません。同じリストを別のマップに保存するだけです。新しいリストが必要な場合、コードは次のようになります。

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);
}
于 2012-06-20T11:17:50.477 に答える
0

すべてのコードを分析せずに:

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);
}

このコードの後、gapFusedには、remindGapsのエントリのコピーであるエントリが含まれるため、これらのエントリは同じオブジェクト(キーと値)を参照します。したがって、一方のマップでエントリを追加または削除しても、もう一方のマップには影響しませんが、一方のマップを介してアクセスする値を変更すると、もう一方のマップを介してアクセスする値も変更されます(たとえば、remingGaps.get(1) ).add( "hello"))。

コードで使用されている「newList」という名前は、新しいリストではなく、既存のリストの単なる参照であるため、混乱を招きます。

于 2012-06-20T11:18:21.813 に答える
0

の値MapはanArrayListであり、浅いコピーを実行しているため(つまり、新しいものは最初のマップMapと同じものを参照している)、2番目のマップのリストへの変更は最初のマップに反映されます。これを回避するには、新しいを作成するときにリストのディープコピーを作成する必要があります。ListsMapMap

于 2012-06-20T11:18:52.433 に答える