繁体   English   中英

Java 8流:替换流集合中的单个项目

[英]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()来隔离我想要识别的元素,但这看起来像是在filtermap之后发生的操作在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM