Java 更新集合中的项目
我有一个Java中对象的Java 更新集合中的项目,java,performance,collections,Java,Performance,Collections,我有一个Java中对象的集合,我需要获取一个特定的项来更新它的属性。我可以使用stream和filter获取项目并对其进行更新,也可以使用.remove()和.add()替换旧对象 我的问题是,哪一种方法的性能更好,一般来说,每种方法的优缺点是什么 e、 g publicstaticvoidmain(字符串[]args) { 收集车=新的ArrayList(); 添加(新车(1,“福特”,“浮动”10000); 增加(新车(2辆,“菲亚特”(浮动)15000); 添加(新车(2辆,“宝马”,浮
集合
,我需要获取一个特定的项来更新它的属性。我可以使用stream
和filter
获取项目并对其进行更新,也可以使用.remove()
和.add()
替换旧对象
我的问题是,哪一种方法的性能更好,一般来说,每种方法的优缺点是什么
e、 g
publicstaticvoidmain(字符串[]args)
{
收集车=新的ArrayList();
添加(新车(1,“福特”,“浮动”10000);
增加(新车(2辆,“菲亚特”(浮动)15000);
添加(新车(2辆,“宝马”,浮动)20000);
//方法1
汽车更新Car=新车(2,“菲亚特”,浮动35000);
Car newCar=cars.stream().filter(c->c.getId().equals(updateCar.getId()).collect(toList()).get(0);
newCar.setPrice(updateCar.getPrice());
//方法2
汽车更新Car=新车(2辆,“菲亚特”(浮动)15000);
汽车。移除(更新汽车);
updateCar.setPrice((浮动)35000);
cars.add(updateCar);
}
你看得不对:在考虑性能时,你的切入点应该是时间复杂性。然后您可以深入研究实现细节
在您的例子中,这两个方法都以O(n)运行
如果性能如此重要,请使用O(1)算法,例如使用
HashMap你看得不对:考虑性能时,你的切入点应该是时间复杂度。然后您可以深入研究实现细节
在您的例子中,这两个方法都以O(n)运行
如果性能如此重要,请使用O(1)算法,例如使用HashMap解决方案3:使用地图按其ID存储每辆车。这是ID的目标,正确使用它
因此,更新只需要map.get(id).setPrice(newprice)
另一个注意事项:当您想要获取一个潜在元素时,不要使用collect()。
流具有用于并行方法的findFirst()或findAny()。
所以
将具有更好的性能。解决方案3:使用地图按其ID存储每辆车。这是ID的目标,正确使用它
因此,更新只需要map.get(id).setPrice(newprice)
另一个注意事项:当您想要获取一个潜在元素时,不要使用collect()。
流具有用于并行方法的findFirst()或findAny()。
所以
将具有更好的性能。如果ID不唯一,则您提出的方法1将不准确。例如,如果你想换宝马,你会换菲亚特,因为他们有相同的id
无论如何,最有效的方法可能是既不过滤也不删除/插入,而是更新,除非您的对象是不可变的,或者您使用了Set
如果您真的关心性能,您应该使用唯一的ID和映射
,而不仅仅是集合
,如果ID不是唯一的,您提出的方法1将不准确。例如,如果你想换宝马,你会换菲亚特,因为他们有相同的id
无论如何,最有效的方法可能是既不过滤也不删除/插入,而是更新,除非您的对象是不可变的,或者您使用了Set
如果您真的关心性能,那么应该使用唯一的ID和映射
,而不是单纯的集合
这两者都不会产生性能,因为时间复杂度将为O(n)。如果您真的从性能的角度来看,请使用HashMap put和get。它将始终给出O(1)
例如:
映射put和get时间复杂度始终为O(1)
Map carsMap=newhashmap();
汽车平均价格(1辆,新车(1辆,“福特”,“浮动”10000);
汽车平均价格(2辆,新车(2辆,菲亚特)(浮动)15000);
//汽车更新价值
Car newCar=carsMap.get(2);
新车定价((浮动)35000);
carsMap.put(2辆新车);
两者都不会产生性能,因为时间复杂度为O(n)。如果您真的从性能的角度来看,请使用HashMap put和get。它将始终给出O(1)
例如:
映射put和get时间复杂度始终为O(1)
Map carsMap=newhashmap();
汽车平均价格(1辆,新车(1辆,“福特”,“浮动”10000);
汽车平均价格(2辆,新车(2辆,菲亚特)(浮动)15000);
//汽车更新价值
Car newCar=carsMap.get(2);
新车定价((浮动)35000);
carsMap.put(2辆新车);
您的两种方法在性能方面都没有多大意义
方法1
一个直接的解决办法是
Integer idToUpdate = 2;
float newPrice = 35000;
cars.stream()
.filter(c -> idToUpdate.equals(c.getId()))
.forEach(car -> car.setPrice(newPrice));
方法2
由于Car
的相等性仅基于ID,因此无需使用旧属性初始化新的Car
实例
请注意,由于您没有指定集合类型,我们不知道它是否包含重复项。因此,直截了当的变体是
Car updateCar = new Car(2, "Fiat", 35000);
do {} while(cars.remove(updateCar));
cars.add(updateCar);
或者,为了确保出现的次数不会改变:
Car updateCar = new Car(2, "Fiat", 35000);
int num = 0;
while(cars.remove(updateCar)) num++;
cars.addAll(Collections.nCopies(num, updateCar));
但这仍然可能会更改集合元素的顺序(如果特定集合类型具有顺序)
显然,第一个变体要简单得多,并且保留源集合的属性,这比微小的性能差异更重要。除非集合是一个集合
,否则这两个操作都意味着线性开销,可以通过使用从id到实例的映射来避免这种开销。您的两种方法在性能方面都没有多大意义
方法1
一个直接的解决办法是
Integer idToUpdate = 2;
float newPrice = 35000;
cars.stream()
.filter(c -> idToUpdate.equals(c.getId()))
.forEach(car -> car.setPrice(newPrice));
方法2
由于Car
的相等性仅基于ID,因此无需使用旧属性初始化新的Car
实例
请注意,由于您没有指定集合类型,我们不知道它是否包含重复项。因此,直截了当的变体是
Car updateCar = new Car(2, "Fiat", 35000);
do {} while(cars.remove(updateCar));
cars.add(updateCar);
或者,确保事件的数量不会改变
Integer idToUpdate = 2;
float newPrice = 35000;
cars.stream()
.filter(c -> idToUpdate.equals(c.getId()))
.forEach(car -> car.setPrice(newPrice));
Car updateCar = new Car(2, "Fiat", (float)15000); // unnecessary use of old values
cars.remove(updateCar);
updateCar.setPrice((float)35000);// just to update the property
cars.add(updateCar);
Car updateCar = new Car(2, "Fiat", 35000);
do {} while(cars.remove(updateCar));
cars.add(updateCar);
Car updateCar = new Car(2, "Fiat", 35000);
int num = 0;
while(cars.remove(updateCar)) num++;
cars.addAll(Collections.nCopies(num, updateCar));