Java:将classA的集合转换为classB的集合

发布于 2024-11-14 09:01:24 字数 410 浏览 3 评论 0原文

给定 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 而无需手动遍历列表,特别是因为我的输入列表可能很大。
如果没有,你们知道编译器是否做了任何优化吗?我主要担心的是性能。

谢谢!

--
拉帕尔

Given a List of Foo myFoos, I need to map those to a collection of a different class, say Bar. I do it like this now:

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

So, is there an easier way to do this? Granted this is pretty easy, but I'm wondering if there's any magic out there that would morph the foos to bars without having to manually walk the list, particularly because my input list can be big.
If not, do you guys know if the compiler does anything to optimize this? I'm worried mainly about performance.

Thanks!

--
Llappall

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

睫毛上残留的泪 2024-11-21 09:01:24

您无法真正避免遍历列表,因为您必须转换每个项目!

但是,如果您编写一个采用 FooBar 构造函数,则可以简化语法。然后你的循环可以变成:

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

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

You can't really avoid walking the list, because you have to convert every item!

But you can simplify your syntax if you write a Bar constructor that takes a Foo. Then your loop can become:

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

Depending on your scenario, an alternative is to not create the list of Bars at all. Instead, you can simply add a Foo.getAsBar() method, so that you dynamically generate a Bar object as required. If the number of elements in the container is higher than the total number of times that you'll need to access them, then this may be more efficient.

云醉月微眠 2024-11-21 09:01:24
public Bar(Foo f){
  this.a = f.a;
  this.b = f.b;
}



for (Foo f : myFoos){
  myBars.add(new Bar(f));
}
public Bar(Foo f){
  this.a = f.a;
  this.b = f.b;
}



for (Foo f : myFoos){
  myBars.add(new Bar(f));
}
春夜浅 2024-11-21 09:01:24

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

拉取属性

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

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

<代码>

公共类酒吧{
  福福;
  公共酒吧(Foo foo){
      this.foo = foo;
  }
  公共 int getPropertyA() {
      返回 foo.getPropertyA();
  }
  公共 int getAnotherProperty() {
      返回 foo.getAnotherProperty();
  }
}

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

One idea which is not a general solution, but could be appropriate in some situations:

Pull the properties

Instead of pushing the properties from Foo to Bar whenever a Bar is instantiated, just associate a Foo to a new Bar and map the properties in the property getters.

  • This is good, if not all instances / properties of Bar will be accessed by clients anyway.
  • But there is a preformance penalty, if Bar instances / properties are accessed repeatedly by clients.

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

This does not prevent you from looping over Foos to instantiate Bars. But it delays the effort to map properties.

段念尘 2024-11-21 09:01:24

另一个想法,当然,只适用于极少数情况。

实现(某种)Fyweight 模式

先决条件:属性集FooBar 是一样的。

  • FooBar 的公共属性放入外部类中,例如 Properties
  • 为 Foo 和 Bar 实现 Properties 类型的属性。
  • 当您创建 Bar 的新实例并希望从 Foo 初始化它时,只需将 Properties 从 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
    }

Another idea, which is - granted - approriate in very rare cases only.

Implement (kind of) a Fyweight pattern

Prerequisite: The set of properties of Foo and Bar is the same.

  • Put the common properties of Foo and Bar into an external class, say Properties.
  • Implement a property of type Properties for Foo and Bar.
  • When you create a new instance of Bar and want to initialize it from Foo, just pass the Properties from the Foo instance to the new Bar instance.

Pros:

  • No need to create copies of properties

Cons:

  • Property set must be the same for Foo and Bar
  • Extra indirection (=overhead) at property access
  • Changes to the properties of Bar affect the originating properties of 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
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文