gpt4 book ai didi

Java Stream 有状态的 findFirst

转载 作者:行者123 更新时间:2023-11-30 10:10:34 24 4
gpt4 key购买 nike

以下方法是用于选择歌曲的加权随机选择算法的一部分。

我想将下面的方法转换为使用流,以确定它是否更清晰/更可取。我不确定这是否可能,因为计算是有状态的操作,取决于列表中的位置。

public Song songForTicketNumber(long ticket)
{
if(ticket<0) return null;
long remaining = ticket;
for(Song s : allSongs) // allSongs is ordered list
{
rem-=s.numTickets; // numTickets is a long and never negative
if(remaining<0)
return s;
}
return null;
}

更正式地说:如果 nallSongs 中每个 Song 对象的所有 Song::numTickets 的总和>,然后对于 0n-1 的任何整数,上述方法应返回列表中的一首歌曲。将返回特定 Song 对象 x 的整数数量将由 x.numTickets 确定。特定歌曲的选择标准是一系列连续整数,由两者numTickets 属性和列表中每个项目的numTickets 属性确定在它的左边。正如目前所写,范围之外的任何内容都将返回 null。

注意:可以修改超出范围的行为以适应 Streams(除了返回 null)

最佳答案

与基本的 for 或 for-each 循环相比,Stream 的效率视情况而定。在您的代码中,Stream 很可能低于您当前的代码的效率,其中主要原因如下:

  1. 如您所述,您的函数是有状态的。使用此方法维护状态可能意味着欺骗 BinaryOperator 的某种匿名实现以与 Stream.reduce 一起使用,结果会变得更庞大且更难以阅读比你当前的代码。
  2. 您在当前循环中短路,没有任何Stream 操作会反射(reflect)出这种效率,尤其是结合#1 考虑这一点。
  3. 您的集合是有序的,这意味着流将以与现有循环非常相似的方式遍历元素。根据集合的大小,您可能parallelStream 中获得一些效率,但在这种情况下必须保持顺序将意味着流效率较低。

切换到 Stream 的唯一真正好处是内存消耗的差异(您可以让 allSongs 离开内存并让 Stream 以更节省内存的方式处理它),这在这里似乎不适用。

总而言之,由于 Stream 操作编写起来会更加复杂,并且可能会损害您的效率(如果有的话),因此我建议您不要进行此更改。

话虽如此,我个人无法想出一个基于 Stream 的解决方案来实际回答您关于如何将这项工作转换为 Stream 的问题。同样,这将是涉及 reducer 或类似物的复杂而奇怪的事情......(如果这还不够,我会删除这个答案。)

关于Java Stream 有状态的 findFirst,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52767208/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com