循环和流-在这种情况下该如何做?

时间:2018-12-12 04:21:26

标签: java

给出:

@Entity
public class Pixel {
    @Id
    Point position;
    String color;

我存储这样的像素:

for (int row = 0; row < 20; row++) {
    for (int col = 0; col < 20; col++) {
        repository.save(new Pixel(new Point(row, col), "w3-flat-turquoise"));
    }
}

这代表20x20的正方形

现在我需要使用布局显示该列表。

我可以很容易地显示一个正方形(工作中):

现在,我想从数据库中检索像素并显示它们……但是我找不到合适的方法。

到目前为止,我有这个功能(因为最后的“ i”无法更改,因此无法正常工作):

VerticalLayout lines = new VerticalLayout();
HorizontalLayout line;
int width = 20;
List<Pixel> pixels = pixelRepository.findAll();

for(final int i=0;i<width;++i) {
    line = new HorizontalLayout();
    Stream<Pixel> pixelLine = pixels.stream().filter(pixel -> pixel.getPosition().x == i);
    for(int j=0;j<width;++j) {
        addNewColorButton(line, pixelLine.filter(pixel -> pixel.getPosition().y == j).findFirst().get().color);
    }
    lines.add(line);
}
add(lines);

什么是合适的算法?

具有最终变量的有效解决方案:

VerticalLayout lines = new VerticalLayout();
HorizontalLayout line;
int width = 20;
List<Pixel> pixels = pixelRepository.findAll();

for(int i=0;i<width;++i) {
    int finalI = i;
    line = new HorizontalLayout();
    Supplier<Stream<Pixel>> pixelLine = () -> pixels.stream().filter(pixel -> pixel.getPosition().x == finalI);
    for(int j=0;j<width;++j) {
        int finalJ = j;
        addNewColorButton(line, pixelLine.get().filter(pixel -> pixel.getPosition().y == finalJ).findFirst().get().color);
    }
    lines.add(line);
}
add(lines);

2 个答案:

答案 0 :(得分:1)

您可以仅通过i创建一个最终对象,该对象会更改i的值。 finalI的值是最终的,永远不变。

int finalI = i;
int finalJ = j;

这是添加final对象之后的代码

VerticalLayout lines = new VerticalLayout();
HorizontalLayout line;
int width = 20;
List<Pixel> pixels = pixelRepository.findAll();

for (int i = 0; i < width; ++i) {
    int finalI = i;
    line = new HorizontalLayout();
    Stream<Pixel> pixelLine = pixels.stream().filter(pixel -> pixel.getPosition().x == finalI);
    for (int j = 0; j < width; ++j) {
        int finalJ = j;
        addNewColorButton(line, pixelLine.filter(pixel -> pixel.getPosition().y == finalJ).findFirst().get().color);
    }
    lines.add(line);
}
add(lines);

答案 1 :(得分:0)

for(final int i=0;i<width;++i)出于明显原因是伪造的。

如果您需要将i放入lambda,则可以将其转换为一个数组,如下所示,编译器会将其视为effectively final

int[] wrapped_i = new int[]{i}

并使用wrapped_i[0]从lambda内部访问它。这种方法在某些情况下容易出错且无法完全解决,特别是当您使用并行流时(那种sorta-kinda是整个卖点)。