Java: преобразование коллекции classA в коллекцию classB - PullRequest
3 голосов
/ 08 июня 2011

Учитывая список 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 в бары без необходимости обхода списка вручную, особенно потому, что мой входной список может быть большим.
Если нет, знаете ли вы, ребята, компилятор делает что-нибудь, чтобы оптимизировать это? Я беспокоюсь в основном о производительности.

Спасибо!

-
Llappall

Ответы [ 4 ]

7 голосов
/ 08 июня 2011

Вы не можете избежать просмотра списка, потому что вам нужно конвертировать каждый предмет!

Но вы можете упростить синтаксис, если напишите конструктор Bar, который принимает Foo. Тогда ваш цикл может стать:

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

В зависимости от вашего сценария, альтернативой является вовсе не создавать список Bar s. Вместо этого вы можете просто добавить метод Foo.getAsBar(), чтобы при необходимости динамически генерировать объект Bar. Если количество элементов в контейнере превышает общее количество раз, которое вам потребуется для доступа к ним, это может быть более эффективным.

2 голосов
/ 08 июня 2011
public Bar(Foo f){
  this.a = f.a;
  this.b = f.b;
}



for (Foo f : myFoos){
  myBars.add(new Bar(f));
}
0 голосов
/ 09 июня 2011

Другая идея, которая предоставляется - оценивается только в очень редких случаях.

Реализация (вид) Весовой шаблон

Необходимое условие: набор свойств Foo и Bar одинаков.

  • Поместите общие свойства Foo и Bar во внешний класс, скажем, Properties.
  • Реализация свойства типа Properties для Foo и Bar.
  • Когда вы создаете новый экземпляр Bar и хотите инициализировать его с Foo, просто передайте Свойства из экземпляра Foo в новый Bar экземпляр.

Плюсы:

  • Нет необходимости создавать копии свойств

Минусы:

  • Набор свойств должен быть одинаковым для Foo и Bar
  • Дополнительная косвенность (= накладные расходы) при доступе к собственности
  • Изменения свойств Bar влияют на исходные свойства Foo.

<code>
    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
    }
0 голосов
/ 09 июня 2011

Одна идея, которая не является общим решением, но может быть уместна в некоторых ситуациях:

Вытащить свойства

Вместо того, чтобы толкать свойства из Foo в Bar каждый раз, когда создается экземпляр Bar, просто свяжите Foo с новым Bar и сопоставьте свойства в методах получения свойств.

  • Это хорошо, если не все экземпляры / свойства Bar будут доступны клиентам в любом случае.
  • Но существует штраф за предварительную производительность, если клиенты / экземпляры Bar повторно обращаются к клиентам.

</p> <blockquote> <pre><code>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. Но это задерживает усилия по отображению свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...