使用 Java 8,我想要两个组合为集合:一个集合是 java.util.List
;另一个是 com.fasterxml.jackson.databind.node.ArrayNode
。
这是处理该问题的非 Java 8 方法:
private void mergeMemberAndRelationshipData(final List<JsonNode> members, final ArrayNode relationships) {
assert members != null : "members cannot be null";
assert relationships != null : "relationships cannot be null";
for (int i = 0; i < members.size(); i++) {
final ObjectNode relationship = (ObjectNode) relationships.get(i);
final JsonNode member = members.get(i);
if (member != null && !member.hasNonNull(ExceptionMapper.errorCodeStr)) {
relationship.put(FIRST_NAME, this.jsonHelpers.safeGetString(member, FIRST_NAME));
relationship.put(LAST_NAME, this.jsonHelpers.safeGetString(member, LAST_NAME));
relationship.put(EMAIL, this.jsonHelpers.safeGetString(member, EMAIL));
relationship.put(MEMBER_SINCE, this.jsonHelpers.safeGetString(member, MEMBER_SINCE));
} else {
LOGGER.error("No corresponding Member, {}, found for Relationship: {}", member, relationship);
}
}
}
我想直播。我喜欢溪流。好吧,那么我们来试试吧:
private void mergeMemberAndRelationshipData(final List<JsonNode> members, final ArrayNode relationships) {
assert members != null : "members cannot be null";
assert relationships != null : "relationships cannot be null";
int i = 0;
members.stream().forEach(member -> {
final ObjectNode relationship = (ObjectNode) relationships.get(i++);
if (member != null) {
relationship.put(FIRST_NAME, this.jsonHelpers.safeGetString(member, FIRST_NAME));
relationship.put(LAST_NAME, this.jsonHelpers.safeGetString(member, LAST_NAME));
relationship.put(EMAIL, this.jsonHelpers.safeGetString(member, EMAIL));
relationship.put(MEMBER_SINCE, this.jsonHelpers.safeGetString(member, MEMBER_SINCE));
} else {
LOGGER.warn("No corresponding member found for relationship: {}", relationship);
}
});
}
但是不,这是行不通的:我在封闭范围内定义的局部变量必须是最终的或实际上是最终的
。是的,这是有道理的。有点。
好吧,所以我想流式传输一个集合 A
,并且对于 A
中的每个对象,对集合 B 中的相应对象执行一些操作
。我需要知道索引才能做到这一点。
如何在匿名函数内部使用在匿名函数范围之外声明的计数器?
我可以通过创造性的方式解决这个问题:
private void mergeMemberAndRelationshipData(final List<JsonNode> members, final ArrayNode relationships) {
assert members != null : "members cannot be null";
assert relationships != null : "relationships cannot be null";
int[] i = new int[1];
i[0] = 0;
members.stream().forEach(member -> {
final ObjectNode relationship = (ObjectNode) relationships.get(i[0]);
i[0] = i[0]++;
if (member != null) {
relationship.put(FIRST_NAME, this.jsonHelpers.safeGetString(member, FIRST_NAME));
relationship.put(LAST_NAME, this.jsonHelpers.safeGetString(member, LAST_NAME));
relationship.put(EMAIL, this.jsonHelpers.safeGetString(member, EMAIL));
relationship.put(MEMBER_SINCE, this.jsonHelpers.safeGetString(member, MEMBER_SINCE));
} else {
LOGGER.warn("No correspodning member foudn for relationship: {}", relationship);
}
});
}
或者我可以这样使用 AtomicInteger
:
AtomicInteger i = new AtomicInteger(0);
...
final ObjectNode relationship = (ObjectNode) relationships.get(i.getAndIncrement());
但这是对 AtomicInteger
的误用;这意味着线程之间共享值。不完全是这里发生的事情,而且它太重量级了,不适合使用(在我看来,请随意不同意我的观点)。
因此,这是很常见的事情(链接两个有序列表并对其元素进行操作)。在 Java 8 之前,这非常简单(技术上仍然如此,但我确信你们这些学究们明白我的意思)。有没有一种 Java-8 的方法可以使用流来完成这个任务?
对于我工作的环境,我们使用微服务架构方法。这意味着我们有一堆服务负责一组离散的、封装的职责(例如,MemberService 处理成员 CRUD,CompanyService 处理公司 CRUD)。最重要的是,我们有一个编排/身份验证/授权服务,可以发出这些不同的调用,然后将它们缝合在一起。因此,在我粘贴的方法中,这是编排层,我在其中获取两个数据集,现在我想将它们合并在一起。这就是为什么我没有 LinkedList 或其他类似的解决方案。
最佳答案
您想要查找压缩。 Java 最初内置了一个 zip 实用程序,但后来被删除了。这是过去的 stackoverflow 响应,用于使用示例实现来进行流压缩:Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip) .
除此之外,为了避免在外部保留索引,您可以使用 IntStream
:
final List<String> a = Arrays.asList("a", "b", "c");
final List<String> b = Arrays.asList("1", "2", "3");
IntStream.range(0, Math.min(a.size(), b.size()))
.mapToObj(i -> a.get(i) + "-" + b.get(i))
.forEach(System.out::println);
关于java - 如何在匿名函数中使用计数器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38254397/