[英]Java: Most efficient way to map properties of one list of objects to another
我正在寻找一种有效的设计模式,以将一个对象列表映射到另一个对象列表,并且它们之间具有零或一对一的关系。 我意识到这种事情通常是在关系数据库中完成的,但是在这种特殊情况下,确实需要在Java应用程序中完成...
假设第一个列表包含Foo
对象(即List<Foo>
):
public class Foo {
public Integer id;
public String barName;
}
第二个列表包含Bar
对象(即List<Bar>
):
public class Bar {
public Integer fooId;
public String name;
}
如何最有效地将Bar
所有name
属性映射到Bar.fooId
等于Foo.id
的Foo
对象?
我能想到的最好的是:
void mapFooBar(List<Foo> fooList, List<Bar> barList) {
for (Bar bar : barList) {
for (Foo foo : fooList) {
if (bar.fooId.equals(foo.id)) foo.barName = bar.name;
}
}
}
编辑:基于几个答案,我改进了我的代码,如下所示:
void mapFooBar(List<Foo> fooList, List<Bar> barList) {
Map<Integer, String> barMap = new HashMap<Integer, String>();
for (Bar bar : barList)
barMap.put(bar.fooId, bar.name);
for (Foo foo : fooList)
if (barMap.containsKey(foo.id)) foo.barName = barMap.get(foo.id);
}
有没有更好的办法?
复杂度为N * M
,这意味着如果您有5个foo和8个bar,则必须执行40次循环
class Container{
List<Foo> foos;
List<Bar> bars;
}
如果使用Map<Integer, Container>
,则为N + M
(5 + 8 = 13次)
遍历两个列表一次并用id
映射它
另请参阅
嗯。 假设“主键”是唯一的,我可以将Bar的列表转换为以fooId作为键,整个对象或名称作为值的映射。 然后,我将遍历Foo的列表,并查看id属性是否存在于地图中。 如果可以,我会将bar.name映射到foo.barName;。
我认为您正在寻找的是类似Apache BeanUtils或Springs的实现。 只要确保要在两个对象之间复制数据的属性名称相同即可。 所以拿你的代码:
void mapFooBar(List<Foo> fooList, List<Bar> barList) {
for (Bar bar : barList) {
for (Foo foo : fooList) {
if (bar.fooId.equals(foo.id)) {
BeanUtils.copyProperties(foo, bar);
}
}
}
}
现在复制已完成,让我们看一下您的循环。 最好的选择是使用fooId作为键将对象保留在地图中(假设没有重复的对象)。
void mapFooBar(Map<Integer, Foo> fooMap, Map<Integer, Bar> barMap) {
for (Integer key : fooMap.keySet()) {
if (barMap.containsKey(key) {
Bar bar = barMap.get(key);
Foo foo = fooMap.get(key);
BeanUtils.copyProperties(foo, bar);
}
}
}
看看Orika,这是一种高效的Java对象到对象的映射
在Java 1.8中,您可以这样编写:
void mapFooBar(List<Foo> fooList, List<Bar> barList) {
Map<Integer, String> barMap = new HashMap<Integer, String>();
barList.stream()
.forEach(bar -> barMap.put(bar.fooId, bar.name));
fooList.stream()
// replaces if statement
.filter(foo -> barMap.containsKey(foo.id))
// update the bar name
.forEach(foo -> {
foo.barName = barMap.get(foo.id);
});
}
您可以使用HashMap存储所有Foo对象,并将其id作为键。
然后遍历栏列表并直接访问所需的HashMap位置
有各种各样的对象映射库旨在解决此问题。 您可能要签出的特别之一是ModelMapper 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.