forEach()不应该尊重排序,但这里似乎尊重,为什么?

时间:2015-06-19 06:22:34

标签: java foreach lambda java-8

我一直在尝试自己做一些基本的GA实现。我使用了一个包含二进制位的类Gene,一个Chromosome类,其ArrayListgenesGene个对象。在Chromosome类中,我有一个评估方法value(),它只计算染色体中位的十进制等效值。 toString()类中重写的Chromosome方法使用lambda表达式创建ArrayList Gene中包含的genes对象中位的String表示形式。我的问题是:由于forEach()方法不应该遵循排序(为了并行性的好处),为什么它总是返回基础位的正确字符串表示,即按照它们的创建顺序?还是我错过了一些严肃的事情?可能是因为染色体长度很短,这种排序的“不尊重”在这里并不突出?

这是我的课程。

Gene

public class Gene {

    private short value;

    public Gene() {
        value = (short) (Math.random() <= 0.5 ? 0 : 1);
        System.out.print(value);
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }
}

Chromosome

import java.util.ArrayList;
import java.util.Arrays;

public class Chromosome {

    private ArrayList<Gene> genes;

    public Chromosome(int numOfGene) {
        this.genes = new ArrayList<>();
        for (int i = 0; i < numOfGene; i++) {
            this.genes.add(i, new Gene());
        }
    }

    public int value() {
        return Integer.parseInt(this.toString(), 2);
    }

    @Override
    public String toString() {
        StringBuilder chromosome = new StringBuilder("");

        genes.stream().forEach((g) -> chromosome.append(g));

        return chromosome.toString();
    }

    public static void main(String[] args) {
        Chromosome c = new Chromosome(10);
        System.out.println("");
        System.out.println(c);
    }
}

Gene构造函数中的print语句是查看基因的创建顺序。无论我运行多少次程序,forEach()总是给出正确的位表示,这对我来说很困惑。或者我完全不知道这应该如何工作,我不知道: - (

3 个答案:

答案 0 :(得分:2)

由于您使用的是顺序流,因此会保留输入列表的顺序。如果将其更改为

genes.parallelStream().forEach((g) -> chromosome.append(g));

您可能会得到不同的订单。

答案 1 :(得分:1)

由于基因是一个ArrayList,并且List是有序的,所以你基本上是根据你添加东西的方式打印List。基本上,第一个要打印的是第一个输入的。

如果是parallelStream,则顺序是随机的。

看看这个link,它以一种很好的方式解释了forEach。

答案 2 :(得分:0)

给出了优秀的答案!但是我想为未来的读者添加这个,因为我发现bajada93给出的链接非常清楚地说明了这一点。

  

创建流时,除非另行指定,否则它始终是串行流。要创建并行流,请调用Collection.parallelStream操作。

Link: JavaSE tutorial