2013-08-09 3 views
3

У меня есть массив с типом B[]. У меня есть конструктор A(B b).Инициализировать массив с помощью конструктора классов и другого массива

Я хочу создать массив с типом A[], используя их.

Я могу использовать оператор for для этого, но я хочу знать, есть ли более удобный (более короткий) способ сделать это. (Синтаксис языка, статический метод или что-то еще)

public class A { 
    public A(B b) { 
     A.a = B.a; 
     A.b = B.b * B.c; 
     ... 
    } 
} 

public class B { 
    ... 
} 

public class C { 
    public static B[] getBs() { 
     B[] bs; 
     ... 
     return bs; 
    } 
} 

void process() { 
    // From here 
    B[] bs = C.getBs(); 
    A[] as = new A[bs.length]; 
    for (int i=0; i<bs.length; i++) { 
     as[i] = new A(bs[i]); 
    } 
    // To here 
} 
+2

Ваша логика, объясняющая, как связаны два массива, довольно отрывочна для меня. Может быть, это я, но если у вас нет хороших ответов, подумайте об этом немного. например, что это означает: 'A.b = B.b * B.c;'? Почему вы используете тип, B, в корпусе конструктора A, а не в параметре b? Что будет 'A.c'? Как элемент A.b является элементом массива? И, наконец, и самое главное, пожалуйста, напишите * настоящий * код, а не * sort-of maybe * code, который, по-видимому, является тем, что вы публикуете здесь. –

+0

Да, пожалуйста, постарайтесь опубликовать реальный код. Мы можем помочь больше, если мы сможем увидеть именно то, что вы пытаетесь сделать, вместо того, чтобы видеть то, что вы, возможно, думаете об этом. – Bmize729

ответ

4

По состоянию на тока состояние языка , о лучшее, что вы можете сделать, это что-то вроде этого :

interface Transformer<A, B> { 
    B transform(A a); 
} 

class ArrayUtils { 
    @SuppressWarnings("unchecked") 
    public static <A, B> B[] transformArray(
     Class<B> clazz, 
     A[] a, 
     Transformer<A, B> transformer 
    ) { 
     B[] b = (B[])Array.newInstance(clazz, a.length); 
     for(int i = 0; i < a.length; i++) { 
      b[i] = transformer.transform(a[i]); 
     } 
     return b; 
    } 
} 

Использование:

Foo[] foos = // some Foo array 
Bar[] bars = 
    ArrayUtils.transformArray(
     Bar.class, 
     foos, 
     new Transformer<Foo, Bar>() { 
      public Bar transform(Foo foo) { return new Bar(foo); } 
     } 
    ); 

Это предполагает:

class Foo { } 
class Bar { public Bar(Foo foo) { } } 

: Есть признаки, приезжающие в 2014 году, что будет проще (?).

: Запомнить мальчики и девочки, the next time you design a type system of your own from scratch, remember to add generics early, rather than adding them on later.

: Просто взломали это вместе. Не стесняйтесь исправлять любые ошибки.:-)

+1

Эти функции описаны в [моем ответе] (http://stackoverflow.com/a/18139765/758280);) – Jeffrey

+0

@Jeffrey: Awesome. :-) – jason

+0

ИМХО, это слишком много, слишком много шаблонов. Я бы пошел с пользовательским циклом, который намного более легкий, чистый, надежный и дружественный к IDE. Шаблоны должны использоваться, чтобы сделать дизайн более очевидным, а не меньше. – fernacolo

3

Пока нет. В Java 8 у нас будет доступ к дополнительным функциям functional programming благодаря Project Lamda, таким как map functions.

В Java 8, следующее было бы справедливо:

B[] bs = C.getBs(); 
List<A> aList = Stream.of(bs).map(b -> new A(b)).collect(Collectors.toList()); 
A[] as = aList.toArray(new A[aList.size()]); 

Это использует lamda expression, и несколько других new features1, 2.

Хотя это не может быть много «короче» Stream обеспечивает parallelization by default, так что если вы изменили Stream.of(bs) к Stream.of(bs).parallel() в приведенном выше примере, он будет выполнять гораздо лучше с большими массивами на многоядерной машине.

/редактировать
Вы можете также использовать method reference вместо лямбда-выражения:

map(A::new) вместо map(b -> new A(b))

+0

ИМХО, по-прежнему думаю, что цикл гораздо читабельнее. – fernacolo

+0

@fernacolo В определенной степени это так, но он все еще гораздо менее масштабируемый. – Jeffrey

+0

Согласитесь о масштабируемости. Тем не менее, чтобы стоять задача создания и синхронизации, либо количество элементов должно быть массивным (примерно 10 тыс. Или более), либо создание каждого элемента должно быть интенсивным вычислением. Нити всегда вводят индетерминизм (предположим, что создание B использует кэш ...). – fernacolo

1

По состоянию на Java 7, вы уже используете самую короткую петлю:

for (int i = 0; i < bs.length; ++i) { 
    as[i] = new A(bs[i]); 
} 

Однако, если вы используете коллекции вместо массивов, вы можете использовать "для каждого":

for (B b: bs) { 
    as.add(new A(b)); 
} 

Коллекции также предоставят вам другие гибкие возможности и ярлыки.

Смежные вопросы