3个嵌套的for-each循环作为Java流

ezykj2lf  于 11个月前  发布在  Java
关注(0)|答案(3)|浏览(87)

在我目前正在做的项目中,我们有三个嵌套的for循环结构:

final Vector3i startPos = new Vector3i(-3, -2, -3);
final Vector3i finishPos = new Vector3i(3, 4, 3);
final Vector3i currentPos = entity.getPos();
  
final List<Vector3i> entityFinderZone = new ArrayList<>();

for (int x = startPos.getX(); x <= finishPos.getX(); x++)
{
    for (int y = startPos.getY(); y <= finishPos.getY(); y++)
    {
        for (int z = startPos.getX(); z <= finishPos.getZ(); z++)
        {
            Vector3i newPos = currentPos.offset(x ,y ,z);
            if (newPos.getX() == 0 && newPos.getZ() == 0 && (newPos.getY() < -1 || newPos.getY() > 2))
            {
                entityFinderZone.add(newPos);
            }
         }
    }
}

字符串
我想用流来做这一切,以使它更快,但我得到错误

final IntStream xCoords = IntStream.iterate(startPos.getX(), i -> i <= finishPos.getX(), i -> i + 1);
final IntStream yCoords = IntStream.iterate(startPos.getY(), i -> i <= finishPos.getY(), i -> i + 1);
final IntStream zCoords = IntStream.iterate(startPos.getZ(), i -> i <= finishPos.getZ(), i -> i + 1);        

entityFinderZone = xCoords.
                flatMap( x -> yCoords.
                        flatMap(y -> zCoords.
                                flatMap(z -> currentPos.offset(x, y, z)))).collect(Collectors.toList());


错误:

Bad return type in lambda expression: Vector3i cannot be converted to int


我做错了什么?

ee7vknir

ee7vknir1#

我想做的所有这一切与流,使它更快
好的。我将把你的问题解释为“我如何使这个更快”。
首先,不是通过使用Lambdas。这不会使任何事情更快。Lambdas,最佳情况下,让您更容易并行化任务,但这不是免费的,并且几乎总是如果任务对性能至关重要,必须并行化,你想要控制这个过程,而不仅仅是要求流尽最大努力(这是你所能做的一切-没有保证,也没有关于它如何做到这一点的特定结构)。
总的来说,“我会使用Paddas,因为它们更快”是一种不正确的心态。
总的来说,“我会使用Bundas,因为它们更好”是一种不正确的心态。
正确的心态是:“我可以用QED来做这件事。如果我能预见到代码在表面上更容易阅读和维护(即不是用循环推理,如'每个人都知道QED更容易阅读,因此使用QED会使它更容易阅读,QED')-那么我将使用它们。如果不是,我不会”。
第一个月
如果你只想做这个的话,三重循环会使这个效率非常低。
如果if没有触发,你的循环什么也不做。只看if,我们有一些布尔属性:

  • 对于[startPos.x, finishPos.x]范围内的一个或零个数字,[startPos.x, finishPos.x]的x偏移量(对于函数来说是常数)是0。如果没有这样的数字,那么这个方法什么都不做,我们可以'什么都不做'的最快方法就是尽可能快地返回。否则,在startPos.x-finishPos.x中循环是绝对没有意义的-除了那个数字之外什么都没有发生。
  • 同样的逻辑也适用于[startPos.z, finishPos.z]范围。
  • 对于y组件,newPos.getZ() > 2不可能是true -毕竟,newPos.getZ()必须是0,否则我们甚至不会到达这里。&&意味着AND:* 所有3个条件都必须成立 *。因此,归结为newPos.getY() < -1,这意味着有一个[startPos.y, endPos.y]的子范围,我们必须循环-我们可以减少一些循环的大小。

这使得你的3-deep循环变成了1-deep循环,效率大大提高。这就是你如何让它更快的方法。用另一种代码结构替换一种代码结构不会带来任何算法复杂度的差异,甚至不会给你带来恒定的(即大多数不相关,但仍然)速度提升-如果有的话,它会减慢速度。

耶,我怎么才能让它更快?

1.计算使newPos的x分量为0的范围内的奇异x值。这是一个简单的加法/减法,然后是范围检查。* 不涉及任何循环 *。
1.对z做同样的事情。
1.现在循环,只针对y。一旦y "超出范围“(newPos.getY()为0或更大),就跳出-它永远不会回到范围内。
使用基本的循环(不使用循环),这些事情都很简单。

lp0sw83n

lp0sw83n2#

首先,似乎你使用了错误的变量startPos,而不是startPose,而且似乎你试图将newPos(类型为Vector3i)添加到entityFinderZone列表中,该列表需要int类型的元素。
要修复此错误,您可以修改lambda表达式以从newPos中提取所需的值并将其添加到列表中。下面是代码的更新版本:

for (int x = startPose.getX(); x <= finishPos.getX(); x++) {  
        for (int y = startPose.getY(); y <= finishPos.getY(); y++) {  
            for (int z = startPose.getZ(); z <= finishPos.getZ(); z++) {  
                Vector3i newPos = currentPos.offset(x, y, z);  
                if (newPos.getX() == 0 && newPos.getZ() == 0 && (newPos.getY() < -1 || newPos.getZ() > 2)) {  
                    entityFinderZone.add(newPos);  
                }  
            }  
        }

字符串

ztmd8pv5

ztmd8pv53#

尝试以下操作。

final List<Vector3i> entityFinderZone = new ArrayList<>();
IntStream.rangeClosed(startPos.getX(), finishPos.getX())
         .forEach(x -> IntStream.rangeClosed(startPos.getY(), finishPos.getY())
                                .forEach(y -> IntStream.rangeClosed(startPos.getZ(), finishPos.getZ())
                                                       .forEach(
                                                           z -> {
                                                               Vector3i newPos = currentPos.offset(x, y, z);
                                                               if (newPos.getX() == 0 && newPos.getZ() == 0 && (newPos.getY() < -1 || newPos.getY() > 2))
                                                                   entityFinderZone.add(newPos);
                                                           })));

字符串

相关问题