![](/img/trans.png)
[英]How to stream, in java, over a key->collection map, where each streamed element is the key and every element in the collection?
[英]Java 8 stream: replace single item in streamed collection
我在使用Java 8时有些新手,并且正在重构一些旧的代码(对于流操作来说似乎是一个很好的用例)。 较旧的代码“有效”,但在我看来它看起来效率很低。
我的问题的简短版本是我试图找到List的单个元素并用相同元素的更新版本替换它(键是相同的,但每次调用代码时属性都有不同的值) 。
try
{
List<Object> items = lookup(itemCache.getKey());
for (int i = 0; i < items.size(); i++)
{
Object originalObject = items.get(i);
if (originalObject.getPropValue() == newObject.getPropValue())
{
List<Object> newItems = new ArrayList<>(items);
newItems.set(i, newObject);
putIntoCache(newObject.getKey(), newItems);
break;
}
}
}
catch (Exception ex) { /*exception handling*/ }
基于我到目前为止所读到的关于流的内容,似乎我需要使用.map()
或.filter()
来隔离我想要识别的元素,但这看起来像是在filter
或map
之后发生的操作在stream语句中,不是在完整列表上运行,也不在列表中运行,其中每个项都受.map()
。
这似乎很简单,但我正在努力绕过它。 因为初始查找是List
本身,所以我认为流可以替换所有这些。 ArrayList<>()
出现在原始代码中,但只要我能够用其键替换该项,那么项的排序就不重要了。
如果您选择帮助,谢谢。
你可以简单地做:
List<Object> newItems = items.stream()
.map(o -> o.getPropValue() == newObject.getPropValue() ? newObject : o)
.collect(toList());
putIntoCache(newObject.getKey(), newItems);
您要应用的函数是“替换与prop值匹配的第一个元素”。 第一部分(和break语句)是非平凡的(因为您依赖于之前处理的所有条目)。 换句话说,它意味着你的函数依赖于一些额外的状态,所以域可以表示为boolean * String
,其中boolean告诉你是否已经完成了替换。 你可以看到它开始变得难看。
如果您可以替换所有匹配值,那么Jean Logeart的答案似乎没问题。
Streams实际上并不是特别适合这段代码,因为它具有早期break
并同时适用于索引和元素。
您可以构建这样的等效语句:
List<Object> items = lookup(itemCache.getKey());
IntStream.range(0, items.size())
.filter(i -> items.get(i).getPropValue() == newItem.getPropValue())
.findFirst()
.ifPresent(i -> {
List<Object> newItems = new ArrayList<>(items);
newItems.set(i, newObject);
putIntoCache(newObject.getKey(), newItems);
});
这真的更好吗? 在我看来,不是特别的。 我们并没有真正使用任何流功能,只是用API替换控制流语法。
如果确切的行为不那么重要,那么可能会有更好的例子,比如Jean的回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.