gpt4 book ai didi

java - 限制一个流,看看是否有挂起的元素

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:30 32 4
gpt4 key购买 nike

我有以下代码要转换为 Java 8 流:

public ReleaseResult releaseReources() {
List<String> releasedNames = new ArrayList<>();

Stream<SomeResource> stream = this.someResources();

Iterator<SomeResource> it = stream.iterator();
while (it.hasNext() && releasedNames.size() < MAX_TO_RELEASE) {
SomeResource resource = it.next();
if (!resource.isTaken()) {
resource.release();
releasedNames.add(resource.getName());
}
}

return new ReleaseResult(releasedNames, it.hasNext(), MAX_TO_RELEASE);
}

方法someResources()返回 Stream<SomeResource>ReleaseResult类如下:

public class ReleaseResult {

private int releasedCount;

private List<String> releasedNames;

private boolean hasMoreItems;

private int releaseLimit;

public ReleaseResult(List<String> releasedNames,
boolean hasMoreItems, int releaseLimit) {

this.releasedNames = releasedNames;
this.releasedCount = releasedNames.size();
this.hasMoreItems = hasMoreItems;
this.releaseLimit = releaseLimit;
}

// getters & setters
}

到目前为止我的尝试:

public ReleaseResult releaseReources() {

List<String> releasedNames = this.someResources()
.filter(resource -> !resource.isTaken())
.limit(MAX_TO_RELEASE)
.peek(SomeResource::release)
.map(SomeResource::getName)
.collect(Collectors.toList());

return new ReleasedResult(releasedNames, ???, MAX_TO_RELEASE);
}

问题是我无法找到一种方法来了解是否有待处理的资源。我想过使用 releasedNames.size() == MAX_TO_RELEASE ,但这没有考虑资源流恰好 MAX_TO_RELEASE 的情况。元素。

有没有办法对 Java 8 流执行相同的操作?

注意:我不是在寻找像“你不必用流做所有事情”“使用循环和迭代器就可以”这样的答案“。如果使用迭代器和循环是唯一的方法或最好的方法,我没意见。只是我想知道是否有一种简单的方法可以做到这一点。

最佳答案

既然你不想听到你不需要所有的流,循环和迭代器很好,让我们通过展示一个干净的解决方案来证明它,而不是依赖于 peek:

public ReleaseResult releaseReources() {
return this.someResources()
.filter(resource -> !resource.isTaken())
.limit(MAX_TO_RELEASE+1)
.collect(
() -> new ReleaseResult(new ArrayList<>(), false, MAX_TO_RELEASE),
(result, resource) -> {
List<String> names = result.getReleasedNames();
if(names.size() == MAX_TO_RELEASE) result.setHasMoreItems(true);
else {
resource.release();
names.add(resource.getName());
}
},
(r1, r2) -> {
List<String> names = r1.getReleasedNames();
names.addAll(r2.getReleasedNames());
if(names.size() > MAX_TO_RELEASE) {
r1.setHasMoreItems(true);
names.remove(MAX_TO_RELEASE);
}
}
);
}

这假定 //getters & setters 包含 ReleaseResult 的所有非 final 字段的 getters 和 setters。 getReleasedNames() 通过引用返回列表。否则,您将不得不重写它以提供一个专门的 Collector 具有对 ReleaseResult 的特殊非公共(public)访问权限(实现另一种构建器类型或临时存储将是不必要的复杂化,它看起来就像 ReleaseResult 已经完全针对该用例设计了)。

我们可以得出结论,对于任何不适合流的内部操作的非平凡循环代码,您可以找到一个收集器解决方案,其功能基本上与 accumulator 函数中的循环相同,但是遭受总是必须提供 combiner 功能的要求。好的,在这种情况下,我们可以在前面加上一个 filter(...).limit(...) 这样还不错...

我刚刚注意到,如果您敢于将其与并行流一起使用,则需要一种方法来扭转释放组合器中最后一个元素的效果,以防组合大小超过 MAX_TO_RELEASE。通常,限制和并行处理永远不会发挥很好的作用。

关于java - 限制一个流,看看是否有挂起的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36041475/

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