Java:将一个对象列表的属性映射到另一个对象列表的最有效方法

时间:2014-03-01 00:26:43

标签: java list loops design-patterns mapping

我正在寻找一种有效的设计模式,将一个对象列表映射到另一个对象列表,它们之间具有零或一对一的关系。我意识到这种事情通常是在关系数据库中完成的,但在这种特殊情况下,它确实需要在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;
}

如何最有效地将所有name属性从Bar映射到Foo等于Bar.fooId的{​​{1}}对象?

我能想到的最好的是:

Foo.id

编辑:基于多个答案,我改进了我的代码如下:

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;
        }
    }
}

有更好的方法吗?

7 个答案:

答案 0 :(得分:1)

这具有N * M的复杂性,这意味着如果你有5个foo和8个bar,则必须执行循环40次

class Container{

  List<Foo> foos;
  List<Bar> bars;

}

如果您使用Map<Integer, Container>,则N + M(5 + 8 = 13次)

迭代两个列表并将其映射到id


另见

答案 1 :(得分:1)

嗯。假设“主键”是唯一的,我可能会将Bar列表转换为以fooId作为键并且整个对象或名称作为值的映射。然后我将遍历Foo列表并查看id属性是否存在于地图中。如果是这样,我会将bar.name映射到foo.barName;

答案 2 :(得分:1)

我认为您正在寻找的是类似Apache BeanUtilsSprings的实现。只需确保要在两个对象之间复制数据的属性名称相同。所以拿你的代码:

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);
    }
  }
}

答案 3 :(得分:1)

看看Orika,一个高效的Java对象到对象映射

https://github.com/orika-mapper/orika

答案 4 :(得分:1)

在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);
        });
}

答案 5 :(得分:0)

您可以使用HashMap存储所有Foo对象,其id为key。

然后遍历Bar列表并直接访问你想要的HashMap位置

答案 6 :(得分:0)

有各种对象映射库旨在解决此问题。您可以查看的一个特别是ModelMapper