List.clear()影响另一个未触动的变量

时间:2016-07-20 01:08:40

标签: java

我正在制作一个java程序,使用遗传算法进行多序列比对。起初,我遇到了JavaHeap错误,因为我创建了太多实例。所以我尝试通过使用list的clear()方法重用对象来修复它。但是,当我使用clear()时,它会影响另一个变量变为null。这是我的代码片段:

private void crossover() throws Exception {
    Collections.shuffle(p);
    p1 = p.pop();
    p2 = p.pop();
    System.out.println("CROSSOVER antara " + p1 + " dan " + p2);
    p.add(p1);
    p.add(p2);

    Collections.shuffle(cutPoint);
    cp = cutPoint.pop();
    cutPoint.add(cp);

    k1 = pop.get(getPOP(p1)).getKromosom();
    k2 = pop.get(getPOP(p2)).getKromosom();
    System.out.println("k1 [" + k1.size() + "]" + k1.toString()); //PRINT1
    System.out.println("k2 [" + k2.size() + "]" + k2.toString()); //PRINT1

    c1.clear();
    c2.clear();
    c1a.clear();
    c2a.clear();
    c1b.clear();
    c2b.clear();

    int maxLength = pop.get(getPOP(p1)).maxLength;
    int kromosomSize = k1.size();
    int point = -1;
    for (int i = 0; i < kromosomSize; i++) {
        System.out.println("k1 [" + k1.size() + "]" + k1.toString()); //PRINT2
        System.out.println("k2 [" + k2.size() + "]" + k2.toString()); //PRINT2
        System.out.println("");
        if (k1.get(i) == maxLength) {
            point++;
        }
        if (point < cp) {
            c1a.add(k1.get(i));
            c2a.add(k2.get(i)); //ERROR
        } else {
            c1b.add(k1.get(i));
            c2b.add(k2.get(i));
        }

    }
    c1.addAll(c1a);
    c1.addAll(c2b);
    c2.addAll(c2a);
    c2.addAll(c1b);
    Individu C1 = new Individu(c1, "f.fasta");
    Individu C2 = new Individu(c2, "f.fasta");
    C1.calculateFitness();
    pop.add(C1);
    C2.calculateFitness();
    pop.add(C2);
}

当我运行程序时,它在某些时候运行。几代之后就会产生错误:

    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
    at java.util.LinkedList.get(LinkedList.java:476)
    at SKRIPSI.GA.crossover(GA.java:120)
    at SKRIPSI.GA.siklusGA(GA.java:224)
    at SKRIPSI.GA.main(GA.java:249)
Java Result: 1

 GA.java:120 pointed at c2a.add(k2.get(i));

然后我尝试在PRINT1和PRINT2处打印k1和k2变量。当错误发生时,在PRINT2处,k2变为空。这是一个例子:

PRINT1
k1 [27][5, 4, 11, 6, 16, 9, 13, 10, 2, 15, 8, 17, 2, 10, 7, 15, 9, 11, 4, 3, 12, 6, 17, 0, 1, 7, 17]
k2 [27][0, 11, 13, 1, 10, 8, 15, 16, 14, 7, 3, 17, 16, 11, 8, 10, 13, 14, 4, 3, 15, 9, 17, 12, 3, 9, 17]

PRINT2
k1 [27][5, 4, 11, 6, 16, 9, 13, 10, 2, 15, 8, 17, 2, 10, 7, 15, 9, 11, 4, 3, 12, 6, 17, 0, 1, 7, 17]
k2 [0][]

在PRINT1和PRINT2之间没有变量k1和k2的修改。如果我改为这个错误,那么这个错误就会消失:

List<Integer> k1 = pop.get(getPOP(p1)).getKromosom();
List<Integer> k2 = pop.get(getPOP(p2)).getKromosom();
List<Integer> c1 = new LinkedList<>();
List<Integer> c2 = new LinkedList<>();
List<Integer> c1a = new LinkedList<>();
List<Integer> c2a = new LinkedList<>();
List<Integer> c1b = new LinkedList<>();
List<Integer> c2b = new LinkedList<>();

但是我收到了JavaHeap错误,因为我制作的实例太多了。

UPDATE1: 这是getPop方法,只返回数字:

public int getPOP(int p) {
        return popSIZE - p - 1;
    }

int maxLength = pop.get(getPOP(p1)).maxLength;仅反向返回数字。例如popSIZE=10p=3,则maxLength将选择pop.get(6)。maxLength。 maxLength是个人对象内的属性。这是指定maxLength的行:

int temp = 0;



     for (int i = 0; i < f.size(); i++) {
            if (temp < f.getSequence(i).length()) {
                temp = f.getSequence(i).length();
            }
        }
maxLength = (int) (Math.ceil((double) (temp * k))); 

k是一些双(在我的情况下为1.2),f是序列数据库。

pop是一个ArrayList:List<Individu> pop = new ArrayList<>();,所以get是调用那些列表的方法。

此外,在第一代k1和k2工作正常,第二代错误显示。并且只在这个方法中调用k2,我搜索没有其他方法调用k2。我试图在一夜之间解决这个问题,这是显示错误的正确行(因为当我点击错误时它会直接将我带到错误行)。也许NetBeans指向错误可能是错的?

UPDATE2: 因为在这种情况下maxLength总是27,所以我尝试将其更改为int maxLength = 27;,但仍然显示错误。

您可以在此处下载完整代码:https://www.dropbox.com/sh/ish2lxh4jzro8zq/AADJfobUR8GUW7nzXtcpjyINa?dl=0

1 个答案:

答案 0 :(得分:-1)

您在k2上执行get而不先检查其大小。如果列表小于您传递的索引(或者 - 更极端的情况 - 如果列表为空),那就是预期的。