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

Pat*_*ick 12 java java-stream

我在使用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*/ }
Run Code Online (Sandbox Code Playgroud)

基于我到目前为止所读到的关于流的内容,似乎我需要使用.map()或者 .filter()隔离我想要识别的元素,但这似乎也就像在流语句中的任何一个filter或之后发生的操作一样map完整列表或列表中每个项目都受到影响.map().

这似乎很简单,但我正在努力绕过它.因为初始查找List本身,我认为流可以取代所有这些.该ArrayList<>()原代码出现,但项目的顺序并不重要,只要我能够通过它的键替换项目.

如果您选择帮助,谢谢.

Jea*_*art 24

你可以简单地做:

List<Object> newItems = items.stream()
    .map(o -> o.getPropValue() == newObject.getPropValue() ? newObject : o)
    .collect(toList());
putIntoCache(newObject.getKey(), newItems);
Run Code Online (Sandbox Code Playgroud)

  • 注意语义差异.原始代码最多替换一次,如果未找到匹配则不执行任何操作,此代码将替换所有实例,并始终创建和发布新列表.除此之外,您可以将其简化为:`items.stream().map(o - > o.getPropValue()== newObject.getPropValue()?newObject:o).collect(toList())` (5认同)
  • 如果合同是`newItems`是缓存中数据的可变副本,则可以使用`newItems.replaceAll()`而不是`Stream`. (3认同)