2014-02-05 2 views
4

У меня есть класс Foo, для которого я сделал класс обертки эквивалентности WrappedFoo, чтобы изменить его контракт equals() в некоторых частях программы.Как обернуть каждый объект коллекции в Java?

Мне нужно скопировать из Foo объектов в объекты WrappedFoo и наоборот во многих местах. Но мне также нужно преобразовать Collection s из Foo s и WrappedFoo от одного к другому. Есть ли способ, которым я могу достичь этого в общем виде?

В основном я хочу метод, который, как это:

public static Collection<WrappedFoo> wrapCollection(Collection<Foo> collection) 

Проблема заключается в том, что я не знаю, какой Collection реализации будет использоваться, и я хотел бы сохранить ту же реализацию для результирующей Collection.

+0

NB: 'Collection' является' interface' и, следовательно, имеет 'реализацию (ы)', а не "подклассы". – Alnitak

+0

@ Alnitak исправлено;) Спасибо – qwertzguy

ответ

2

Использование Reflection API, вы могли бы сделать что-то вроде этого (обратите внимание на 0 в имени метода):

public static Collection<WrapperFoo> wrapCollection0(Collection<Foo> src) 
{ 
    try 
    { 
     Class<? extends Collection> clazz = src.getClass(); 
     Collection dst = clazz.newInstance(); 
     for (Foo foo : src) 
     { 
      dst.add(new WrapperFoo(foo)); 
     } 
     return dst; 
    } catch(Exception e) 
    { 
     e.printStackTrace(); 
     return null; 
    } 
} 

Теперь реализовать целую кучу методов перегрузки один вкладыш с использованием метода выше (обратите внимание на 0 в вызовах):

public static ArrayList<WrapperFoo> wrapCollection(ArrayList<Foo> src) 
{ 
    return (ArrayList<WrapperFoo>) wrapCollection0(src); 
} 

public static Vector<WrapperFoo> wrapCollection(Vector<Foo> src) 
{ 
    return (Vector<WrapperFoo>) wrapCollection0(src); 
} 

... 
+0

Это в основном два решения, которые я придумал, но они оба не идеальны: я предпочитаю не писать кучу подобных методов, и я предпочитаю избегать использования отражения. Я хотел посмотреть, есть ли более аккуратное решение. Я приму этот ответ, если никто не найдет лучшего решения. – qwertzguy

+0

На самом деле отражение не так уж плохо. Попробуйте оба метода одновременно. Подождите, я отредактирую свой ответ. –

+0

Да, это правда, что это не так уж плохо и кажется лучшим решением на данный момент. Это сломается, если в конкретной реализации Collection нет конструктора args, но я думаю, это довольно редко. – qwertzguy

1

Авось Collections2.transform из библиотеки Google гуавы может обеспечить функциональность, которую вы ищете.

Вы должны иметь возможность передать функцию, которая обертывает элементы Foo в WrappedFoo. Главный вопрос заключается в том, приемлемо ли для новой коллекции рассматривать исходную коллекцию (следовательно, она не будет иметь такую ​​же реализацию, что и исходная коллекция).

+2

transform() возвращает общий набор 'Collection ' не конкретный тип коллекции. Мое понимание требования OP - передать в «Список ' get a List ' – Kent

+0

@Kent. Думаю, мой ответ уместен, так как этот метод соответствует его сигнатуре метода. Я получил свой ответ, отметив, что он возвращает коллекцию представлений. – Mark

2

Интерфейс Collection гарантирует существование «boolean addAll (Collection c)» - метода. я бы просто попробовать что-то вдоль линий theese:

public static Collection<WrappedFoo> wrapFoos(Collection<Foo> col) { 
    Class<?> colClass = col.getClass(); 
    Collection<WappedFoo> newCol = colClass.getConstructor().getInstance(); 
    newCol.addAll(col); 
    return newCol; 
} 
+0

Я не могу 'addAll()', поскольку 'WrappedFoo' не расширяет' Foo'. Однако, выполняя цикл и добавляя каждый из них и вызывая метод, который обертывает 'Foo' в' WrappedFoo', он должен работать. И тогда это соответствует ответу @Martijn Courteaux. Просто я хотел избежать отражения. – qwertzguy

+0

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

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