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

时间:2016-06-03 16:50:54

标签: java python exception-handling java-stream porting

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

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

在没有使用流的情况下写这个很简单,但我认为这是一个学术学习练习,可以更好地理解它们。有没有办法编写代码来替换计数循环并按照尝试使用流?

1 个答案:

答案 0 :(得分:0)

您可以使用以下代码。它避免了实现中的异常和中断。通过正确应用流,算法变得更容易阅读和理解。

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