用流写这个的正确方法是什么?

What is the proper way to write this with streams?

如果异常处理按预期工作,则以下代码应该完成所需的工作:

XVector position = new XVector();
IntStream.range(0, desired_star_count).forEach(a -> {
    // Try to find a position outside the margin of other stars.
    try
    {
        IntStream.range(0, XStarField.patience).forEach(b -> {
            position.random(size);
            error:
            {
                for (XVector point : this.positions)
                    if (position.sub(point).get_magnitude() < min_star_margin)
                        break error;
                throw new XStarField.Found();
            }
        });
    }
    catch (XStarField.Found event)
    {
        this.positions.add(position.copy());
        this.colors.add(Math.random() < 0.5 ? XColor.RED : XColor.BLUE);
    }
});

不幸的是,生成了以下两个错误:

Error:(33, 25) java: unreported exception XStarField.Found; must be caught or declared to be thrown
Error:(37, 13) java: exception XStarField.Found is never thrown in body of corresponding try statement

如果我在Python中写同样的代码,结果可能是这样的:

position = XVector()
for a in range(desired_star_count):
    for b in range(self.patience):
        position.random(size)
        for point in self.positions:
            if abs(position - point) < min_star_margin:
                break
        else:
            self.position.append(position.copy())
            self.colors.append(XColor.RED if random.random() < 0.5 else XColor.BLUE)
            break

如果不使用流,这将很容易编写,但我认为这是一个学术学习练习,可以更好地理解它们。有没有一种方法可以编写代码来替换计数循环并像已经尝试的那样使用流代替它们?

您可以改用以下代码。它避免了实施中的异常和中断。通过正确应用流,该算法更易于阅读和理解。

XVector position = new XVector();
IntStream.range(0, DESIRED_STAR_COUNT).forEach(a -> {
    // Try to find a position outside the margin of other stars.
    IntStream.range(0, PATIENCE).filter(b -> {
        position.random(size);
        return !this.positions.stream().anyMatch(point -> position.sub(point).getMagnitude() < MIN_STAR_MARGIN);
    }).findFirst().ifPresent(b -> {
        this.positions.add(position.copy());
        this.colors.add((XColor) XRandom.sChoice(RED_STAR, BLUE_STAR));
    });
});