我有一个对象列表。我需要从列表中更新匹配我的过滤器的单个对象。我可以做以下事情:
List<MyObject> list = list.stream().map(d -> {
if (d.id == 1) {
d.name = "Yahoo";
return d;
}
return d;
});
但是我担心的是,我就像遍历整个列表,最多可能有2万条记录。我可以先做for loop
,然后再做break
,但我认为那也会很慢。
有什么有效的方法吗?
答案 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
。
您还可以使用List
将Map
转换为Stream
:
Map<Integer, MyObject> map = list.stream()
.collect(Collectors.toMap(
MyObject::getId
Function.identity()
));
toMap
的第一个参数将流项目映射到映射中的相应键(此处为MyObject
的ID),第二个参数将一个项映射到映射值(此处为{ {1}}项目本身。
构造地图会花费一些时间和内存,但是一旦有了地图,按ID搜索项目的速度就非常快。 搜索项目的次数越多,首先构建地图的回报就越大。
但是,如果您只需要更新一个项目然后忘了整个列表,只需搜索正确的元素,对其进行更新就可以了。
如果您的数据已经按ID排序,则可以使用二进制搜索来更快地找到您的项目。
否则,您需要遍历列表,直到找到您的商品。在性能方面,这里没有什么比简单的循环更好。但是,使用 Deadpool 的答案中所示的MyObject
和Stream
也是可以的,并且可以使代码更清晰,这在大多数情况下更为重要。