使用流更新列表中的单个对象

时间:2019-04-11 02:55:24

标签: java java-8

我有一个对象列表。我需要从列表中更新匹配我的过滤器的单个对象。我可以做以下事情:

List<MyObject> list = list.stream().map(d -> {
    if (d.id == 1) {
        d.name = "Yahoo";
        return d;
    }
    return d;
});

但是我担心的是,我就像遍历整个列表,最多可能有2万条记录。我可以先做for loop,然后再做break,但我认为那也会很慢。

有什么有效的方法吗?

3 个答案:

答案 0 :(得分:3)

您可以使用Map而不是列表,并将ID保存为键。 https://docs.oracle.com/javase/8/docs/api/java/util/Map.html

然后您可以使用 Path partPath = Paths.get("yourFileLocation"+"\\"+"yourFileName.ext"); 提取它。

答案 1 :(得分:3)

使用findFirst,以便在列表中找到第一个匹配元素后,其余元素将不被处理

Optional<MyObject> result = list.stream()
                                .filter(obj->obj.getId()==1)
                                .peek(o->o.setName("Yahoo"))
                                .findFirst();

  //will not return anything but will update the first matching object name

                              list.stream()
                              .filter(obj->obj.getId()==1)
                              .findFirst()
                              .ifPresent(o->o.setName("Yahoo"));

答案 2 :(得分:0)

这取决于您需要对输入数据执行此逻辑的频率。

如果碰巧几次,请考虑使用 Raz 建议的Map。 您还可以使用ListMap转换为Stream

Map<Integer, MyObject> map = list.stream()
                                 .collect(Collectors.toMap(
                                     MyObject::getId
                                     Function.identity()
                                 ));

toMap的第一个参数将流项目映射到映射中的相应键(此处为MyObject的ID),第二个参数将一个项映射到映射值(此处为{ {1}}项目本身。

构造地图会花费一些时间和内存,但是一旦有了地图,按ID搜索项目的速度就非常快。 搜索项目的次数越多,首先构建地图的回报就越大。

但是,如果您只需要更新一个项目然后忘了整个列表,只需搜索正确的元素,对其进行更新就可以了。

如果您的数据已经按ID排序,则可以使用二进制搜索来更快地找到您的项目。

否则,您需要遍历列表,直到找到您的商品。在性能方面,这里没有什么比简单的循环更好。但是,使用 Deadpool 的答案中所示的MyObjectStream也是可以的,并且可以使代码更清晰,这在大多数情况下更为重要。