3

给定一个 Foo myFoos 列表,我需要将它们映射到不同类的集合,比如 Bar。我现在这样做:

List<Bar> myBars = new...
for(Foo f : foos) {
    Bar b = new Bar();
    b.setAProperty(f.getProperty);
    b.setAnotherProp(f.getAnotherProp);
    myBars.add(b);
}

那么,有没有更简单的方法来做到这一点?当然这很容易,但我想知道是否有任何魔法可以将 foos 变形为 bar 而无需手动遍历列表,特别是因为我的输入列表可能很大。
如果没有,你们知道编译器是否做了任何优化吗?我主要担心性能。

谢谢!

——
拉帕尔

4

4 回答 4

7

你真的不能避免遍历列表,因为你必须转换每个项目!

但是,如果您编写一个Bar采用Foo. 然后你的循环可以变成:

for(foo f : foos) {
    myBars.add(new Bar(f));
}

根据您的情况,另一种方法是根本不创建Bars 列表。相反,您可以简单地添加一个Foo.getAsBar()方法,以便您Bar根据需要动态生成一个对象。如果容器中的元素数量高于您需要访问它们的总次数,那么这可能更有效。

于 2011-06-08T15:19:47.510 回答
2
public Bar(Foo f){
  this.a = f.a;
  this.b = f.b;
}



for (Foo f : myFoos){
  myBars.add(new Bar(f));
}
于 2011-06-08T15:23:03.503 回答
0

一个想法不是一般的解决方案,但在某些情况下可能是合适的:

拉取属性

每当 Bar 被实例化时,不必将属性从 Foo 推送到 Bar,只需将 Foo 关联到新 Bar 并映射属性 getter 中的属性。

  • 这很好,如果不是所有的 Bar 实例/属性都将被客户端访问。
  • 但是,如果客户端重复访问 Bar 实例/属性,则会有性能损失。

public class Bar {
  Foo foo;
  public Bar(Foo foo) {
      this.foo = foo;
  }
  public int getPropertyA() {
      return foo.getPropertyA();
  }
  public int getAnotherProperty() {
      return foo.getAnotherProperty();
  }
}

这不会阻止您循环 Foos 来实例化 Bars。但它延迟了映射属性的工作。

于 2011-06-09T08:24:17.597 回答
0

另一个想法是 - 被授予 - 仅在极少数情况下才适用。

实现(某种)Fyweight 模式

Foo先决条件:和的属性集Bar相同。

  • 将 和 的公共属性Foo放入Bar外部类中,例如Properties
  • Properties为 Foo 和 Bar实现一个类型的属性。
  • 当您创建一个新实例Bar并希望从 初始化它时Foo,只需将属性从Foo实例传递给新Bar实例。

优点:

  • 无需创建属性副本

缺点:

  • Foo 和 Bar 的属性集必须相同
  • 属性访问时的额外间接(=开销)
  • Bar 属性的更改会影响 Foo 的原始属性。


    public class Properties {
        public int getPropertyA() {..}
        public int getAnotherProperty() {..}
    }
    public class Foo {
        Properties properties;
        public Foo(Properties properties)
            this.properties = properties;
        }
        public Properties getProperties() {
            return properties;
        }
    }
    public class Bar {
        Properties properties;
        public Foo(Properties properties)
            this.properties = properties;
        }
        public Properties getProperties() {
            return properties;
        }
    }
    //Client code:
    //Access properties:
    int i = foo.getProperties().getPropertyA();
    //Map Foos to Bars
    for (Foo foo: foos) {
        Bar bar = new Bar(foo.getProperties());
        //Do something with bar
    }

于 2011-06-09T08:50:43.473 回答