2010-04-30 2 views
2

Основной вопрос Java здесь от настоящего новичка. У меня есть набор объектов Java (класса «MyClass»), которые реализуют определенный интерфейс (интерфейс «MyIfc»). У меня есть набор этих объектов, находящихся в частной переменной в моем классе, который объявляется следующим образом:Каким образом лучше всего преобразовать набор объектов Java в другой набор объектов?

protected Set<MyClass> stuff = new HashSet<MyClass>(); 

Мне нужно, чтобы обеспечить публичный метод, который возвращает этот набор как набор объектов типа «MyIfc».

public Collection<MyIfc> getMyStuff() {...} 

Как мне сделать преобразование? Следующая строка дает мне ошибку, что она не может выполнить преобразование. Я бы догадался, что компилятор знал, что объекты класса MyClass реализовали MyIfc и, следовательно, обработали бы его.

Collection<MyIfc> newstuff = stuff; 

Любое просвещение оценивается.

+1

Как насчет возврата 'Collection '? –

ответ

6

Вероятно, самый правильный способ:

return new HashSet<MyIfc>(stuff); 

Если класс слишком велик, чтобы сделать это, вы можете сделать:

return Collections.unmodifiableSet(stuff); 
+0

Это имеет те же преимущества, что и подход Натана выше, но делает это в одной строке через конструктор, а не вызывает «addAll». По этой причине я считаю, что это лучший ответ. – HDave

1

Вам не нужно преобразовывать. Вам нужно будет ввести stuff как Set<MyIfc>.

Фон: Да, это правильно, если у вас есть объект типа MyClass, он также будет использоваться в качестве экземпляра MyIfc. Но вы явно набрали свой набор по типу MyClass. И это просто нечто иное, чем набор типов MyIfc. В конце концов, у вас также могут быть другие классы, которые реализуют MyIfc, а затем вы также можете поместить их в свой Set<MyIfc>, но не в Set<MyClass>.

+0

Это была бы отличная идея, если бы я мог не рассматривать членов HashSet как MyClass. Однако в моем случае мне нужно это сделать, поэтому я предпочитаю оставить внутреннюю коллекцию как есть. – HDave

3

Компилятор не любит ваше назначение материала для новичка, потому что он открывает возможность помещать вещи в newstuff, которые реализуют MyIfc, но не имеют тип MyClass. Вы можете иметь ваши геттер создать свою собственную коллекцию:

public Collection<MyIfc> getMyStuff() { 
    Collection<MyIfc> coll = new HashSet<MyIfc>(); 
    coll.addAll(myStuff); 
    return coll; 
} 
+0

Мне нравится этот подход, потому что я получаю коллекцию MyClass - в этом случае мне нужно работать с ними как MyClass. – HDave

0

Google collections определите кучу ленивых адаптеров, которые могут быть подходящими для ваших целей.

В частности, это Collections2.transform. Вот пример того, как адаптировать вашу коллекцию:

Collection<MyIfc> newStuff = 
    Collections2.transform(
    stuff, 
    new Function<MyClass, MyIfc>() 
    { 
     public MyIfc apply (final MyClass from) 
     { 
     return (MyIfc) from; // This may throw a ClassCastException though 
     } 
    } 
) 
+0

Кажется, очень странное использование трансформации для меня. Почему бы не использовать материал как 'Set ' внутренне. И beweare ваш код вернет живой просмотр, который делает * not * allow add/addAll. – whiskeysierra

+0

Согласен, не имеет смысла делать все это. –