Dave
Dave

Reputation: 21924

Whats the best to way convert a set of Java objects to another set of objects?

Basic Java question here from a real newbie. I have a set of Java objects (of class "MyClass") that implement a certain interface (Interface "MyIfc"). I have a set of these objects stored in a private variable in my class that is declared as follows:

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

I need to provide a public method that returns this set as a collection of objects of type "MyIfc".

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

How do I do the conversion? The following line gives me an error that it can't do the conversion. I would have guessed the compiler knew that objects of class MyClass implemented MyIfc and therefore would have handled it.

Collection<MyIfc> newstuff = stuff;

Any enlightenment is appreciated.

Upvotes: 3

Views: 26796

Answers (4)

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45616

Google collections define a bunch of lazy adapters, that may be suitable for your purposes.

One in particular is Collections2.transform. Here is an example on how to adapt your collection:

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
      }
    }
  )

Upvotes: 0

Yishai
Yishai

Reputation: 91931

Probably the most correct way is:

    return new HashSet<MyIfc>(stuff);

If the class is too large to do that, you can do:

    return Collections.unmodifiableSet(stuff);

Upvotes: 7

Nathan Hughes
Nathan Hughes

Reputation: 96454

The compiler doesn't like your assignment of stuff to newstuff, because it lays open the possibility of putting things in newstuff that implement MyIfc but are not of type MyClass. You could have your getter create its own collection:

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

Upvotes: 3

Gerd Klima
Gerd Klima

Reputation: 1392

You don't need to do any conversion. You will have to type your stuff as Set<MyIfc>.

Background: Yes, it is correct that if you have an object of type MyClass this will also be usable as a MyIfc instance. But you explicitly typed your Set as of type MyClass. And this is simply something different than a Set of type MyIfc. After all, you could also have other classes that implement MyIfcand then you could also put them into your Set<MyIfc> but not into Set<MyClass>.

Upvotes: 1

Related Questions